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
n
possibilities. Shuffle them (you don't need to shuffle alln
numbers justk
of them by performing the firstk
steps of Fisher Yates). Choose the firstk
. This approach takesO(k)
time (assuming allocating an array of sizen
takesO(1)
time) andO(n)
space. This is a problem ifk
is 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. Ifk
is small relative ton
then 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
?