Я хочу выбрать 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?