洗牌算法(Fisher-Yates Shuffle)深度解析:从每日一题到等概率排列的实战实现

发布时间:2026/11/12 4:12:41

洗牌算法(Fisher-Yates Shuffle)深度解析:从每日一题到等概率排列的实战实现 洗牌算法Fisher-Yates Shuffle深度解析从每日一题到等概率排列的实战实现【免费下载链接】leetcodeLeetCode Solutions: A Record of My Problem Solving Journey.( leetcode题解记录自己的leetcode解题之路。)项目地址: https://gitcode.com/gh_mirrors/le/leetcode本文是仓库每日一题系列中 2019-07-19 洗牌算法题解 的完整扩展版本。题目要求在O(n)时间内随机打乱一个n元数组并保证所有n!种排列等概率出现每种概率恰为1/n!。读完本文你将掌握经典 Fisher-Yates 洗牌算法的核心思路、JavaScript 实现细节、完整的概率正确性证明以及它与仓库中蓄水池抽样、拒绝采样、三门问题等概率类专题的关联脉络。信息卡片该题解收录于 每日一题汇总 的 2019-07-19 条目属于Array与Probability两个标签的交叉内容时间2019-07-19题目链接暂无tagArrayProbability题目描述假设我们有一个 n 个元素的数组要求你实现一个函数该函数会随机地返回 n 个元素的排列要求所有排列出现的概率是一样的。即每一个排列出现的概率都是 1/n!。对题目做三点解读它们正是本题的验收标准必须随机不能引入任何确定性顺序输出由随机源驱动必须是排列洗牌是原地重排元素集合不变只是顺序改变必须等概率n!种排列每一种被产出的概率都严格等于1/n!这是最容易出错、也最需要证明的一点。朴素思路抽取到新数组的问题最直观的想法是像真实洗牌一样从原数组中随机取出一个元素放入另一个全新的数组不断重复直至取空。这种思路的正确性容易理解——每个元素在每个位置上被取到的概率相同。但它有两个明显的缺陷每次取出都涉及数组删除操作在多数语言的动态数组实现中删除中间元素需要移动后续元素导致总复杂度退化到O(n²)额外开辟了一个等长的新数组空间开销为O(n)。核心思路把取出换成交换原文档给出了一个巧妙的转换把从数组中取出的元素放入原数组的末尾用交换代替删除第 1 次随机取出一个元素时把它与原数组的倒数第 1 个元素交换第 2 次在剩余元素中随机取出时把它与原数组的倒数第 2 个元素交换依次类推第n-1次最后一次无需交换完成洗牌。这样每一轮处理区间都在缩小第i轮只在尚未固定的前缀区间[0, n-i]内做随机选择被选中的元素与区间末元素交换后即被钉死在后缀区后续不再参与随机。整个过程只做了n-1次交换时间复杂度为O(n)空间复杂度为O(1)原地操作仅需一个临时变量。注原文档特别说明第一次交换选择与倒数第 1 个而不是第 1 个交换是因为与末尾元素交换代码更简洁——倒序遍历使得循环边界与随机区间边界天然一致无需额外维护已固定前缀的游标。参考实现JavaScript原题解给出的 JS 代码如下function shuffle(list) { for (let i list.length - 1; i 1; i--) { const random (Math.random() * (i 1)) 0; const temp list[i]; list[i] list[random]; list[random] temp; } }逐行拆解代码作用for (let i list.length - 1; i 1; i--)从最后一个位置开始倒序处理i同时充当当前待固定区间的末尾下标i 1保证最后一轮只剩 1 个元素无需再交换Math.random()返回[0, 1)区间的均匀随机小数Math.random() * (i 1)映射到[0, i1)覆盖区间0..i共i1个整数候选 0位运算取整等价于Math.floor对非负数为截断得到0..i的均匀随机整数三行交换把list[random]与list[i]互换位置i从此固定关键点剖析随机区间每轮收缩第i轮只在[0, i]内取随机下标保证已经固定到后缀的元素绝不会被再次选中这是等概率成立的结构性前提 0与Math.floor的等价性Math.random() * (i 1)的结果为非负浮点数右移 0 位即向下取整可安全使用若读者希望可读性更强也可改写为Math.floor(Math.random() * (i 1))原地修改函数直接修改传入的list无返回值是典型的原地算法in-place。概率正确性证明原文档给出了完整的数学证明这里完整保留并展开推导。第一步任意一个元素放在任意位置的概率均为1/n。放在倒数第 1 个位置的概率第一次随机即在n个元素中选中它概率为1/n放在倒数第 2 个位置的概率第一次没被选中概率(n-1)/n第二次在剩余n-1个元素中被选中概率1/(n-1)两者相乘仍为1/n放在倒数第k个位置的概率为[(n-1)/n] × [(n-2)/(n-1)] × ... × [(n-k1)/(n-k2)] × [1/(n-k1)] 1/n中间的每一项都是上一轮未被选中的条件概率逐项约分后恰为1/n。因此每个元素等概率地落在每一个位置上。第二步所有排列等概率概率为1/n!。洗牌等价于依次确定第 1 位、第 2 位、……、第 n 位的元素。某一种特定排列出现的概率为1/n × 1/(n-1) × ... × 1/2 × 1 1/n!其中第k步是从剩余n-k1个元素中精确选中该排列指定的那一个。这与每一个排列出现的概率都是1/n!的题目要求完全吻合。这与仓库中 蓄水池抽样reservoid sampling 的证明思路同源蓄水池抽样把最终被选中的概率拆成被选中的概率 × 不被替换的概率逐轮约分后所有元素最终概率均为k/n洗牌则把每个位置的概率逐轮约分恒为1/n。二者都是通过逐轮收缩随机区间保证等概率思想的体现。复杂度分析指标数值说明时间复杂度O(n)恰好执行n-1轮每轮一次随机数生成与一次交换空间复杂度O(1)原地交换仅使用常数级临时变量i、random、temp扩展与变体从洗牌到更广的概率算法这道题的价值不只在于一个函数它连接了仓库中多条概率类知识线1. 蓄水池抽样随机抽样 k 个当数据规模大到无法全部载入内存如数据流场景洗牌算法无法直接使用。蓄水池抽样 用大小为k的蓄水池边遍历边替换保证每个元素被最终选中的概率都是k/n。当k n时蓄水池抽样退化为一次完整洗牌两者算法骨架一致。2. 拒绝采样用 Rand7 实现 Rand10洗牌对随机源的均匀性要求极高。仓库中的 470. 用 Rand7() 实现 Rand10 展示了如何用两次rand7()生成7 × 7 49个等概率结果再从中等概率选出 10 个并拒绝其余采样如行号列号法取idx 40再取模保证输出均匀——这与洗牌算法从均匀分布出发构造等概率结构的思维一脉相承也提醒我们当随机源不够均匀或范围不匹配时需要显式的构造或拒绝策略。3. 概率问题的实验验证仓库的每日一题系列中有多次以实验验证概率结论的先例。例如 三门问题题解 附带的 三门问题模拟程序通过Math.random()驱动 100 万次模拟验证换门胜率 2/3这一违反直觉的结论。洗牌算法同样可以照此思路用大样本模拟验证每种排列频率趋近1/n!或验证每个元素出现在每个位置上的频率趋近1/n。4. 栈混洗stack shuffle仓库 基础数据结构英文版 提到合法的栈混洗操作与合法的括号匹配表达式一一对应n个元素的栈混洗种类数恰等于n对括号的合法表达式数量即卡特兰数。注意这与本文的随机洗牌是不同概念——栈混洗只允许通过入栈/出栈重排讨论的是能产生多少种排列而非如何等概率产生排列二者可对照学习。总结算法本质Fisher-Yates 洗牌通过每轮收缩随机区间 原地交换把抽取操作改为交换操作将时间复杂度从朴素的O(n²)优化到O(n)空间复杂度降为O(1)正确性依据逐轮约分证明每个元素落在任意位置的概率均为1/n进而每种排列出现概率为1/n!严格满足题目要求实现要点倒序遍历、随机区间[0, i]每轮收缩、 0取整、与末尾元素交换保持代码简洁知识延伸与 蓄水池抽样、Rand7 实现 Rand10拒绝采样、三门问题概率实验验证共同构成仓库中一条完整的概率算法学习路径建议结合原文与相关题解对比阅读、动手验证。【免费下载链接】leetcodeLeetCode Solutions: A Record of My Problem Solving Journey.( leetcode题解记录自己的leetcode解题之路。)项目地址: https://gitcode.com/gh_mirrors/le/leetcode创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/11/9 20:29:58

如何快速导出并可视化微信聊天记录:WeChatMsg 完整指南

如何快速导出并可视化微信聊天记录:WeChatMsg 完整指南 【免费下载链接】WeChatMsg 提取微信聊天记录,将其导出成HTML、Word、CSV文档永久保存,对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com/GitHub_Trending/we/WeCh…

2026/11/9 20:57:07

自适应信号处理实战:LMS与RLS算法原理、Python实现及参数调优

简介:这是一份关于自适应信号处理的PDF学习资料,系统讲解自适应系统的基本概念、信号相关矩阵及其性质、信号与噪声子空间、梯度运算等核心理论,并对比最小均方误差、最大信噪比、最大似然、最小噪声方差等性能准则,梳理最陡下降法…

2026/11/12 4:09:19

遂宁电工证哪里可以办多少钱都别怕学历不高也能报

遂宁电工证哪里可以办多少钱都别怕学历不高也能报 学历不高怕报不上名?别急,电工证其实没你想的那么难!今天咱们就聊聊【遂宁电工证哪里可以办】,顺便说说多少钱、怎么选机构,还有你关心的电子证书怎么查,统统给你安排上。 电工证到底值不值得考?…

2026/11/12 4:09:19

新乡长垣电工证多久拿证外省证能转吗

新乡长垣电工证多久拿证外省证能转吗 之前考的证在外省能不能转过来?这个问题,很多在河南长垣的电工朋友都问过,其实答案是 可以转 ,但需要走正规流程,特别是涉及到 新乡长垣电工证 的 多久拿证 问题,很多人还不太清楚,下面我们一步步说清楚。…

2026/11/12 4:09:18

高级电工证什么时候发报名费多少钱

南阳电工证什么时候发?真实经历告诉你怎么避坑 刚出校门就听说电工证是找工作门槛,结果到手才发现, 高级电工证什么时候发 这个问题,直接卡住了我的入职流程。那会儿我在南阳一家市政工程公司做实习,眼看项目就要开工,偏偏电工证没下来,项目经理当场…

2026/11/12 4:09:18

遂宁电工证哪里可以办 怎么报名不被坑

遂宁电工证哪里可以办 怎么报名不被坑 不知道去哪报名怕被中介坑,你不是一个人。最近我帮朋友代办电工证,结果被几个培训机构坑了,交了钱连培训都没上。这年头, 遂宁电工证哪里可以办…

2026/11/12 4:09:18

姑苏考电工证费用多少 官方报名入口怎么找

姑苏考电工证费用多少 官方报名入口怎么找 学历不高怕报不上名?其实电工证的报考门槛并不高,只要年满18周岁,具备初中及以上学历,身体健康,通过正规渠道报名就可以。尤其是现在国家对安全生产和职业资格认证越来越重视, 电工证…

2026/11/12 4:04:18

电力电缆作业证含金量到底值不值?真实经历告诉你答案

电力电缆作业证含金量到底值不值?真实经历告诉你答案 怕考不过白交培训费?这年头,特种作业证成了不少工友的“刚需”,尤其是电力电缆作业证,含金量到底高不高?其实,这事儿我身边很多人都问过,今天就从咱平顶山市政公用工程从业者的角度,聊聊电力电缆…

2026/11/11 12:42:59

电工证丢失还能补吗?千万别踩坑,丢了证等于失业

电工证丢失还能补吗?千万别踩坑,丢了证等于失业 你正在找工作,但手里的电工证突然丢了,这下怎么办?别急,先别慌, 电工证丢失还能补吗 ?答案是肯定的,但 千万别踩坑 ,补办流程如果不了解,可能会耽误你上岗、甚至影响到你的收入。…

2026/11/12 0:04:01

工地太忙根本没时间复习考试?学习电工证到哪里学通过率揭秘

工地太忙根本没时间复习考试?学习电工证到哪里学通过率揭秘 工地太忙根本没时间复习考试?你不是一个人。作为一名在南阳卧龙区干了七八年市政公用工程的电工,我深知这个问题的现实性。电工证不仅是工作的“入场券”,更是职业发展的“通行证”,但备考过程…

2026/11/12 0:04:01

双流电工证考别怕挂科!郑州报考避坑指南全攻略

双流电工证考别怕挂科!郑州报考避坑指南全攻略 实操考试心里没底怕挂科?双流电工证考在郑州报名,很多人因为不了解流程、准备不充分,白白浪费时间和金钱。作为三门峡应届工程类毕业生,我也曾经历过这样的焦虑。今天就从零开始,手把手教你如何避开郑州报…

2026/11/12 0:04:01

之前考的证在外省能不能转过来 怎么报名考电工证培训价格多少

之前考的证在外省能不能转过来 怎么报名考电工证培训价格多少 之前考的证在外省能不能转过来?这个问题确实让不少准备换城市工作的朋友犯了难,尤其像电工证这种实操性很强的证书,很多人担心跨省后证书能不能继续用。其实,只要符合相关流程,是可以顺利转…

2026/11/11 20:27:01

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/10 10:29:37

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑