I want to choose k elements uniformly at random out of a possible n without choosing the same number twice. There are two trivial approaches to this.
- Make a list of all
npossibilities. Shuffle them (you don't need to shuffle allnnumbers justkof them by performing the firstksteps of Fisher Yates). Choose the firstk. This approach takesO(k)time (assuming allocating an array of sizentakesO(1)time) andO(n)space. This is a problem ifkis very small relative ton. - Store a set of seen elements. Choose a number at random from
[0, n-1]. While the element is in the set then choose a new number. This approach takesO(k)space. The run-time is a little more complicated to analyze. Ifk = theta(n)then the run-time isO(k*lg(k))=O(n*lg(n))because it is the coupon collector's problem. Ifkis small relative tonthen it takes slightly more thanO(k)because of the probability (albeit low) of choosing the same number twice. This is better than the above solution in terms of space but worse in terms of run-time.
My question:
is there an O(k) time, O(k) space algorithm for all k and n?