洗牌问题和 knuth-shuffle 算法
Jul 22, 2021 • 🍻 03min 15s read
🔖 shuffleknuth-shuffle约瑟夫环
对于给定的
约瑟夫环
¶遍历位置
- 时间复杂度:
- 额外空间复杂度:
knuth-shuffle
¶进一步考虑,在 shuffle 问题中,我们并不需要保证每个“人”的相对位置不变,也不必每次从上一个被踢的位置开始继续报数,而是只需要保证剩下的“人”被选出来的概率相同即可;如果能让剩下的人始终紧密地聚集到一起,那么利用数组的索引特性,每次
算法描述
¶- 从第
个位置(最右侧)开始向左遍历位置 - 每次从最左侧到当前位置
上的所有数中随机选择一个数和当前位置的数进行交换
应用上述算法,每个数字出现的概率为:
- 第
个位置上,每个数出现的概率为: - 第
个位置上,每个数出现的概率为: - ...
- 第
个位置上,每个数出现的概率为: - ...
程序实现
¶- 时间复杂度:
- 额外空间复杂度:
knuth-shuffle.ts | 9 lines.
123456789export function knuthShuffle<T extends unknown = unknown>(nodes: T[]): void { const N = nodes.length for (let i = N - 1, j: number, x: T; i > 0; --i) { j = Math.floor(Math.random() * (i + 1)) x = nodes[i] nodes[i] = nodes[j] nodes[j] = x }}