Я хочу выбрать k
элементы равномерно случайным образом из возможного n
, не выбирая один и тот же номер дважды. Есть два тривиальных подхода к этому.
- Составьте список всех возможностей
n
. Перемешайте их (вам не нужно чтобы перетасовать все номераn
толькоk
из них, выполнив первыйk
шагов Фишер Йейтс). Выберите первыйk
. Этот подход занимает времяO(k)
(предполагается, что выделение массива размераn
принимаетO(1)
time) иO(n)
. Это проблема, еслиk
очень малый относительноn
. - Сохраните набор видимых элементов. Выберите случайное число из
[0, n-1]
. Пока элемент находится в наборе, выберите новый номер. Этот подход занимает пространствоO(k)
. Время выполнения немного больше сложный для анализа. Еслиk = theta(n)
, тогда время выполненияO(k*lg(k))=O(n*lg(n))
, потому что это сборщик купонов проблема. Еслиk
мал относительноn
, то он немного более чемO(k)
из-за вероятности (хотя и низкой) выбора тот же номер два раза. Это лучше, чем приведенное выше решение в условия пространства, но хуже с точки зрения времени выполнения.
Мой вопрос:
существует ли O(k)
время, O(k)
пространственный алгоритм для всех k
и n
?