查看: 4710|回复: 19
收起左侧

Google/Microsoft : Random Shuffle

  |只看干货 |刷题
头像被屏蔽

分享帖子到朋友圈
wwwyhx | 显示全部楼层 |阅读模式
提示: 作者被禁止或删除 内容自动屏蔽

上一篇:Google : n 条直线给交点
下一篇:Google : 无限输入流取中数
Imbalism 2011-4-25 22:23:01 | 显示全部楼层
本楼: 👍   0% (0)
 
 
0% (0)   👎
全局: 👍   100% (42)
 
 
0% (0)    👎
有n个元素,给每个元素赋一个1 to n的随机数作为优先级,然后用线性时间将它们排序。如果遇到优先级相同的元素,再给这些元素排序一次。
回复

使用道具 举报

Etrnls 2011-4-25 22:51:46 | 显示全部楼层
本楼: 👍   0% (0)
 
 
0% (0)   👎
全局: 👍   100% (7)
 
 
0% (0)    👎
for (int i = 1; i < n; ++i) swap(x[i], x[rand() % (i + 1)]);
回复

使用道具 举报

Imbalism 2011-4-25 23:18:49 | 显示全部楼层
本楼: 👍   0% (0)
 
 
0% (0)   👎
全局: 👍   100% (42)
 
 
0% (0)    👎
for (int i = 1; i < n; ++i) swap(x, x[rand() % (i + 1)]);
Etrnls 发表于 2011-4-25 22:51


我觉得这样不对,如果通过归纳法来证明的话,假设你前i - 1个数已经取好一个1 to n里面排列了,出现这种排列的概率是 (n - (i - 1))! / n !。
那么,考虑处理到第i个数之后的情况,现在要证明处理完i 个数以后得到的排列出现的概率 (n - i) ! / n !。
设i个元素中出现 <a1 , a2, ...,ai - 1, ax> 排列为事件A。
设i - 1个元素中出现<a1, a2 ... ax, ... ,ai -1>这么个排列为事件B。
设第i次交换时, ax 刚好与原先在i的位置上的元素交换 为事件C。
那么,事件B与事件C同时发生,就得到了事件A。
P(A) = P(B 且 C) = P(C | B)P(B) = 1/ (i - 1) * P(B) = 1 / (i - 1) * (n - (i - 1 )) ! / n ! ,结果不为 (n - i) ! / n !,归纳法失败。
不知道上面的分析对不对,新手上路,跪求指教。
回复

使用道具 举报

lwy.tsinghua 2011-4-25 23:38:09 | 显示全部楼层
本楼: 👍   0% (0)
 
 
0% (0)   👎
全局: 👍   50% (3)
 
 
50% (3)    👎
for(int i=0; i<n; i++) swap(x[n],x[rand()%(n)]);
每次都用数组最后一个数,和前面随机位置的数交换。
回复

使用道具 举报

Etrnls 2011-4-26 00:14:53 | 显示全部楼层
本楼: 👍   0% (0)
 
 
0% (0)   👎
全局: 👍   100% (7)
 
 
0% (0)    👎

评分

参与人数 1大米 +30 收起 理由
diamrem + 30

查看全部评分

回复

使用道具 举报

lwy.tsinghua 2011-4-26 02:46:26 | 显示全部楼层
本楼: 👍   0% (0)
 
 
0% (0)   👎
全局: 👍   50% (3)
 
 
50% (3)    👎
for(int i=0; i
lwy.tsinghua 发表于 2011-4-25 23:38


想错了,更正:
for(int i=0;i<n;i++)  swap( x[n-1-i],x[rand()%(n-i)]);
本质上和Etrnis给的算法相同,只是倒过来了,每次交换后都在缩小问题规模。
回复

使用道具 举报

ljfljf2006 2011-4-26 08:41:59 | 显示全部楼层
本楼: 👍   0% (0)
 
 
0% (0)   👎
全局: 👍   100% (36)
 
 
0% (0)    👎
我有个朋友去腾讯面试,面试官问他如何把一副牌打乱顺序后发给玩家,和这个是一样的。

我当时的第一个想法是,人是怎么洗牌的就让电脑怎么洗牌。一开始总共有n张牌,产生两个随机数a=rand()%n,b=rand()%n,然后把a和b之间的牌移动到牌堆顶层。这时候牌堆顶部有b-a+1张牌,对这b-a+1张牌做前面一样的处理,也就是从中间抽出一部分再放到顶端,直到最后只剩1张牌。可以反复这样处理几遍。

后来自己也觉得上面那方法太麻烦了,老是要移动元素。就想简介点来个swap(rand()%n,rand()%n)。

刚才看到上面几位的回复,发现自己之前的想法真是稀烂。喜欢Imbalism和Etrnls提出的方法。线性啊。

顺便问一句,Imbalism是喜欢到玩dota的imba吗?
回复

使用道具 举报

Imbalism 2011-4-26 08:47:23 | 显示全部楼层
本楼: 👍   0% (0)
 
 
0% (0)   👎
全局: 👍   100% (42)
 
 
0% (0)    👎
回复  Imbalism
Etrnls 发表于 2011-4-26 00:14



非常感谢提供的资源,不知道你说的是不是The modern algorithm这个项里面的算法,我没看过大神的书,可能是我的分析有问题,可能是没理解大神的算法,我去下个电子版的看看他如何证明的。
回复

使用道具 举报

Etrnls 2011-4-26 09:26:00 | 显示全部楼层
本楼: 👍   0% (0)
 
 
0% (0)   👎
全局: 👍   100% (7)
 
 
0% (0)    👎
回复 9# Imbalism

是的
GCC里面的STL的random_shuffle貌似就是这个算法
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

隐私提醒:
■拉群请前往同学同事飞友|拉群结伴版块,其他版块拉群,帖子会被自动删除
■论坛不能删帖,为防止被骚扰甚至人肉,不要公开留微信等联系方式,请以论坛私信方式发送。
■特定版块可以超级匿名:https://tools.1point3acres.com/thread
■其他版块匿名方法:http://www.1point3acres.com/bbs/thread-405991-1-1.html

>
快速回复 返回顶部 返回列表