【LeetCode.384打乱数组】Knuth洗牌算法详解
前两天看网易面筋得知网易云的随机歌曲播放使用了这个算法,遂找题来做做学习一下
【资料图】
打乱数组https://leetcode.cn/problems/shuffle-an-array/
给你一个整数数组 nums ,设计算法来打乱一个没有重复元素的数组。打乱后,数组的所有排列应该是 等可能的。
实现 Solution class:
Solution(int[] nums) 使用整数数组 nums 初始化对象int[] reset() 重设数组到它的初始状态并返回int[] shuffle() 返回数组随机打乱后的结果
示例 1:
输入["Solution", "shuffle", "reset", "shuffle"][[[1, 2, 3]], [], [], []]输出[null, [3, 1, 2], [1, 2, 3], [1, 3, 2]]
解释Solution solution = new Solution([1, 2, 3]);solution.shuffle(); // 打乱数组 [1,2,3] 并返回结果。任何 [1,2,3]的排列返回的概率应该相同。例如,返回 [3, 1, 2]solution.reset(); // 重设数组到它的初始状态 [1, 2, 3] 。返回 [1, 2, 3]solution.shuffle(); // 随机返回数组 [1, 2, 3] 打乱后的结果。例如,返回 [1, 3, 2]
提示:
1 <= nums.length <= 50-106 <= nums[i] <= 106nums 中的所有元素都是 唯一的最多可以调用 104 次 reset 和 shuffle
题目要求的输入是一个整数数组nums,要调用shuffle()函数将其打乱后返回一个乱序数组
暴力法(本方法不是重点,想了解直接看后面的代码,LeetCode官解)
一种很古朴的思路是:
再定义一个数组nums4shuffle,把nums中的所有数都存进nums4shuffle,然后遍历nums4shuffle
假设当前循环变量是i,此时从nums4shuffle中随机选取一个数,作为打乱后的nums的第i个元素
那么要解决的问题有以下几个:
1、如何再次获取数组的初始顺序
2、如何从nums4shuffle中随机取值
Fisher-Yates 洗牌算法在上述问题中,所谓的“打乱”(或者说随机洗牌),其实可以理解为:让每一个元素都等概率地出现在每一个位置
即每个位置都能等概率的放置每个元素
听上去有点耳熟?Knuth 洗牌算法实际上就是一种将数组中元素随机排列的组合问题。
假设有一个长度为
n
的数组arr
,我们需要对其进行随机化操作,使得其中的每个元素都具有相等的可能性出现在任意位置上。这可以理解为是从n
个元素中选择n
个元素不重复地排列的问题,即全排列。因此,根据组合数学的知识,共有n!
种不同的可能性,每一种可能性出现的概率应该是相等的,即为1/n!
。
因此,Knuth 洗牌算法的正确性在于它能够保证每个排列出现的概率相等,并且所有可能的排列构成了一个大小为 n!
的集合。这与概率论中的组合问题有着相似的思路和方法。
该算法使用代码实现起来很简洁,就是一个for循环即可
void knuth_shuffle(vector& arr) { int n = arr.size(); for (int i = 0; i < n; ++i) { // 随机选择一个位置 j,其中 i <= j < n int j = rand() % (n - i) + i; // 交换 arr[i] 和 arr[j] 的值 swap(arr[i], arr[j]); }}
knuth_shuffle
函数是用于执行 Knuth 洗牌算法的函数,它接受一个整数类型的数组 arr
作为输入参数,使用该算法对数组进行随机化操作。
函数中首先获取数组的长度 n
,然后开始遍历数组。在每一轮遍历中,函数会随机选择一个位置 j
,其中 i <= j < n
,也就是从 i 开始到数组末尾之间随机选择一个位置。
这里使用了
rand()
函数来生成随机数,并将其除以取模运算的余数与i
相加,得到最终的位置j
,rand()
函数默认生成的随机数范围是 0 到 RAND_MAX(通常为 32767)。假设n=5,i=2,此时已经到了第二轮循环,前两个数已经被随机交换,现在要在剩下的3个数中进行交换
rand()函数会生成0到32767之间的一个随机整数,我们将它除以(n-i)=3,然后取余数
假设rand()生成的随机整数为10000,则它除以3的结果是3333余1。以此类推,我们就可能得到0~2之间的余数
当前遍历到的位置是2,那么只要在加上2就可以得到一个2~4之间的随机数
根据上面的分析,j
的结果就是n - i
之间的一个随机数
一旦选定了位置 j
,函数就会交换 arr[i]
和 arr[j]
这两个元素的值。
循环结束
这样,每一次遍历都会使得数组中的某个元素被随机地交换到前面的位置上,从而实现了 Knuth 洗牌算法的效果
代码洗牌算法class Solution {public: Solution(vector& nums) { nums4save = nums;//初始化nums4save } vector reset() { return nums4save;//重置数组时只要返回保存的初始数组即可 } vector shuffle() { vector nums4shuffle = nums4save;//定义一个新数组用于打乱顺序 int numsLen = nums4shuffle.size(); //洗牌算法 for(int i = 0; i < numsLen; ++i){//通过for循环选取一个数 //在(i,numsLe]间再随机选择一个数与for循环选择的数进行交换 int random = rand() % (numsLen - i) + i;//计算numsLen - i之间的一个随机数 swap(nums4shuffle[i], nums4shuffle[random]);//交换 } return nums4shuffle;//返回打乱后的数组 }private: vector nums4save;//定义nums4save用于保存初始数组};
暴力法class Solution {public: Solution(vector& nums) { // 构造函数 // 将传入的nums保存到成员变量this->nums中 this->nums = nums; // 创建一个与nums等长的vector original,并将nums的值复制到original中 this->original.resize(nums.size()); copy(nums.begin(), nums.end(), original.begin()); } vector reset() { // 还原为原始顺序 // 将original中的元素值复制到nums中 copy(original.begin(), original.end(), nums.begin()); // 返回nums return nums; } vector shuffle() { // 随机打乱顺序 // 创建一个新的vector shuffled,用于保存随机打乱后的nums vector shuffled = vector(nums.size()); // 创建一个list lst,并将nums中的元素值复制到lst中 list lst(nums.begin(), nums.end()); // 遍历nums for (int i = 0; i < nums.size(); ++i) { // 在lst的元素个数范围内生成一个随机索引j int j = rand()%(lst.size()); // 获取lst中索引为j的元素,并将其赋值给shuffled[i] auto it = lst.begin(); advance(it, j);//将迭代器 it 向前移动 j 个位置,就可以获得对应的随机元素 shuffled[i] = *it; // 从lst中删除索引为j的元素 lst.erase(it); } // 将shuffled中的元素值复制到nums中 copy(shuffled.begin(), shuffled.end(), nums.begin()); // 返回nums return nums; }private: vector nums; // 原始数组 vector original; // 原始顺序};
标签:
推荐
- 【LeetCode.384打乱数组】Knuth洗牌算法详解
- 药店店长工作总结范文示例.doc
- 白落梅简介出生(白落梅简介) 快资讯
- aw是什么意思(awd是什么意思)
- 南方城市为何成为2023年春节十大人口迁出地?|微动态
- 连衣裙带来甜美气息,诠释出时髦气息,曼妙身材尽显-今日热讯
- 天天观速讯丨受天气影响,上海市部分公交、客轮停运停航
- 全球今日报丨美债野蛮生长 国防开支节节攀升
- 荣耀一季度出海战绩公布:欧洲增长4倍,拉丁美洲暴涨700% 全球微资讯
- 镁条在空气中燃烧发出耀眼的白光(镁条在空气中燃烧)
- 今年端午假期或成近五年最火端午
- 猜数字游戏规则海报(猜数字游戏规则) 要闻
- 博纳董事长于冬:剧集的崛起是对电影真正的冲击,不是拼特效的时代了
- 【全球快播报】cad转pdf看不清怎么办(cad转换成pdf看不清楚)
- 水淹道床影响列车运行!合肥发布情况通报_全球微速讯
- 华为获转让问界商标:可用于汽车等 天天快讯
- 焦点滚动:董事长、独董突然辞职!
- 权志龙经纪合约正式到期, YG称计划协商单独合作|世界新要闻
- 观天下!受雷电大风天气影响,上海部分公交、客轮停运停航
- 王楠跪在地上指导女儿打球,鼓掌叫好,老公郭斌:这妈能打90分 环球快播报
- 焦点观察:直角三角形求角度公式表(直角三角形求角度公式)
- 养母的一席话,让寇准迷途知返
- 全球视点!雷暴大风+冰雹 江苏海安一处电力线路遭雷击断线
- 纯国产32核CPU供货 搭载主机开售了
- 长宁非遗空间上新,沪剧如何打动年轻人?_世界短讯
- 7月发布,还有更强的性能旗舰新机
- 广西异地就医直接结算工作取得积极成效 信息
- 资讯:以基础设施角度看待大模型 智源解读行业生态与开源路径思考
- 世界球精选!上海市嘉定区发布大风黄色预警
- 肾活检能查出什么病(肾活检)
- 交通银行董事长任德奇:商业银行参与碳金融市场,有利于活跃市场、提升定价效率_即时
- 卖红酒背熟10句开场白话术?-全球头条
- 【世界新视野】肠悔青!我花499元买了台小屏平板,结果体验还不如用了5年的小米平板4
- 2023年湖南省地质灾害精准转移避险演练在岳阳举行-全球看点
- 360电视直播app下载_360电视直播
- 世界观热点:樊纲:要充分估计需求不足困难,短期内扩需求仍寄希望于投资需求的扩大
- 环球速读:桉木是什么档次的木材(桉木)
- 英国监管机构阻止微软收购动视暴雪 后者获准参与上诉程序_世界微资讯
- 韩国:2025年起将AI引入小中高课程 到2028年实现全面覆盖 世界热门
- 当前消息!河池365_hc365
- 20的螺纹钢筋一米有多少kg(20螺纹钢筋1米多重)
- 塔巫塔罗:射手座季度情感运势,清空过往,才能接纳未来-当前视讯
- 无畏契约东京大师赛6月11日开打,两支中国战队参赛
- 是喝高度还是低度?一位酿酒师告诉你,两者白酒的区别 当前焦点
- 消息!速冻鸡怎么炖好吃?
- 世界今热点:江苏扬州:深化“揭榜挂帅”助企专项行动 发布207项企业技术需求
- 招商必备!全国科技创新链主企业名单在这里!
- 国家乡村振兴局开展农村厕所革命“提质年”
- 猪饲料食品添加剂(如何选择合适的猪饲料添加剂)
- 国内物价运行总体平稳——解读5月份CPI和PPI数据-天天速讯
- 直击2023中国经济传媒大会丨中国经济体制改革研究会副会长樊纲:消费需求一时难以扩大,短期内仍寄希望于投资需求
- 9成产品“赚到钱”!部分债基开始限购
- 牵涉移民!刺童事件挑动法国神经,马克龙:极其卑鄙的袭击-全球信息
- 北京三院地址(北京武警三院)
- 天天播报:千城胜景|石家庄市井陉矿区:夏日绿意浓 矿山披新装
- 2023年6月11日十二星座运势快送
- 法网:焦科维奇晋级决赛
- 赞美老师的诗句或名言唯美 赞美老师的诗句或名人名言
- 如何提速、提效、降本?欧阳明高:动力电池全生命周期智能化 世界微头条
- 【天天新要闻】10大敏感肌专用防晒霜推荐:清爽又控油,好用又不贵!
- 浙江温岭法院推动涉案企业合规建设
- 省级绿色认证先行、“领跑者”名单公布,温州1+5! 世界快讯
- 天天热推荐:《P3重制版》实体盘疑泄露:PS4/5和NS版也曝光!
- 【环球播资讯】追光 | 明晨,看18年后的伊斯坦布尔续写欧冠决赛传奇
- 看点:同事离职了怎么祝福语 口语 同事离职了怎么祝福语
- 酒店不建议12岁以下儿童大厅就餐引争议,您怎么看? 报道
- 网红宏楠女友抢账号,网红宏楠怎么了|环球观点
- 焦点短讯!6月10日起,12306网站试行在线选铺服务!
- 名词解释在线查询软件(在线名词解释)
- 格力空调哪个系列好格力空调型号推荐_格力空调哪个系列好_全球微头条
- 当前快看:土壤改良成效明显 大片盐碱地“变身”丰收田
- 世界热点评!美漫角色系列——绿灯侠
- 环球观察:百济、再鼎跻身美股薪酬排行榜!BMS、AZ领跑,辉瑞逊色,175家美股药企员工薪酬公布!
- 【全球时快讯】美国联邦最高法院裁定亚拉巴马州需重新划分选区
- 6月9日生意社聚丙烯酰胺基准价为14400.00元/吨
- 盘点高考感人瞬间:爱与守护从未缺席
- 再次下调!_环球精选
- 天天信息:用电饭锅木薯要煮多久 用电饭锅煮木薯煮几分钟即可食用呢
- 全球最资讯丨开设给排水专业的大学(给排水专业大学排名)
- 广告材料有哪些广告材料都包括哪些类型_广告材料有哪些广告材料都包括哪些
- 常德高考:考场外的“高考人” 热消息
- 永修政府网站官网(中国永修政府网)
- 视点!木工做的柜子不满意能拆吗怎么办(木工做的柜子不满意能拆吗)
- 当前报道:韩两党欲就日本核污染水排海开听证会,韩媒:能否如期举行是未知数
- 热议:磷酸铁锂VS三元锂,动力赛道的王对王,哪款更适合你?
- 【环球快播报】南京高科(600064):6月8日北向资金增持300.88万股
- 中软国际孙佳韡:所有软件都值得用大模型重做一遍
- 建发致新6月15日深交所首发上会 拟募资4.84亿元
- 要闻:广东空调卖爆了 空调加工车间24小时不停歇
- 同程旅行发布端午旅游趋势:玩水旺季来临 看海、漂流、水乐园受欢迎
- 23烟台蓝天SCP003今日发布发行公告
- 关于做好2023年陕西省普通高校招收定向培养军士工作的通知
- 重庆住房公积金租房提取额度再提高|世界视点
- 紫荆国际金融(08340)完成发行1280万股配售股份|全球滚动
- 世界滚动:武汉新洲:考生到考场发现证件遗忘在车上,新洲警方紧急帮助寻回
- 环球热点!全球RSV疫苗“三国杀”箭在弦上,百亿美元市场争夺战打响
- 揭秘涨停丨龙头超35万手封死涨停,新型城镇化板块大涨 实时焦点
- 当前动态:联想推出拯救者无线上网伴侣:50M 带宽速率,149 元
- 环球视点!工作表上下左右键换格(excel表格上下左右换格)
- 世界今日报丨英大证券一分析师被出具警示函
X 关闭
行业规章
X 关闭