Ни один из них не лучший.Вам нужен тасовка Фишера-Йейтса.Проблема со случайным решением состоит в том, что вы делаете много ненужной работы заранее.Проблема со вторым решением состоит в том, что вероятность дубликатов возрастает со временем, поэтому вы отбрасываете много значений.
Для очень эффективного решения, которое дает вам подмножество ваших значений с ноль возможность дубликатов (и без предварительной сортировки), Fisher-Yates - это путь.
dim n[N] // gives n[0] through n[N-1]
for each i in 0..N-1:
n[i] = i // initialise them to their indexes
nsize = N // starting pool size
do N times:
i = rnd(nsize) // give a number between 0 and nsize-1
print n[i]
nsize = nsize - 1 // these two lines effectively remove the used number
n[i] = n[nsize]
Просто выбрав случайное число из пула, заменив его наверхнее число из этого пула, а затем уменьшение размера пула, вы получаете случайное перемешивание, не беспокоясь о большом количестве перестановок впереди.
Это важно, если число велико, поскольку оно не 't ввести ненужную задержку запуска.
Например, проверьте следующую проверку, выбрав 10-из-10:
<------ n[] ------>
0 1 2 3 4 5 6 7 8 9 nsize rnd(nsize) output
------------------- ----- ---------- ------
0 1 2 3 4 5 6 7 8 9 10 4 4
0 1 2 3 9 5 6 7 8 9 7 7
0 1 2 3 9 5 6 8 8 2 2
0 1 8 3 9 5 6 7 6 6
0 1 8 3 9 5 6 0 0
5 1 8 3 9 5 2 8
5 1 9 3 4 1 1
5 3 9 3 0 5
9 3 2 1 3
9 1 0 9
Вы можете видеть, как пул уменьшается, ипотому что вы всегда заменяете использованный на неиспользованный, у вас никогда не будет повторения.