以文本方式查看主题 - 计算机科学论坛 (http://bbs.xml.org.cn/index.asp) -- 『 C/C++编程思想 』 (http://bbs.xml.org.cn/list.asp?boardid=61) ---- google面试题[讨论] (http://bbs.xml.org.cn/dispbbs.asp?boardid=61&rootid=&id=24957) |
-- 作者:firstway -- 发布时间:12/3/2005 1:55:00 PM -- google面试题[讨论] 有n个人,其中超过半数是好人,剩下的是坏人 现在要你从这n个人当中找出一个好人来,只能通过以下方式: 问通过何种方法才能最快的找出一个好人来, |
-- 作者:firstway -- 发布时间:12/3/2005 3:39:00 PM -- 我现在提一个想法,望大家指正 ------------------------- 先找一个人A,然后其他所有人评价A 1如果半数说A是好人:A是好人 2如果半数以上说A是坏人:A是坏人 ----- 如果A是坏人 去掉说A是好人的人(一定是坏人) 在剩下的人里找一个人重复上面的(这里好人肯定更多于一半) --- 递归进行 最坏情况就是坏人都说实,话且每次运气不好都选出的是坏人 这时复杂度是O(n平方) 实际计算时选出好人的几率越来越高的,因为坏人不断的被去掉 --- 大家有何高见》? |
-- 作者:enorm -- 发布时间:12/3/2005 5:19:00 PM -- 最坏的情况时所有坏人都被选出,前所有坏人说真话,这时才选出好人,最坏情况o(n^2) 最好情况o(n) |
-- 作者:来去如风 -- 发布时间:4/23/2006 5:05:00 PM -- google面试题-------我的解法 路过看了楼主的算法,觉得无法接受,应该是最慢的一个算法,下面是我的想法: 思想是尽量多的排除坏人: 1,如果两个人都说对方是好人,那么有两种可能,要吗都是好人,要吗都是坏人. 2,如果有一个人说对方是坏人,那么两人种至少有一个坏人,可以同时排除,剩下的人照样满足条件好人站半树以上,再在剩下的人中找好人 int people[] = {0,1,1,1,1,0,0,0,1};//N个人的数组1是好人,0是坏人 int samePos = -1, sameNum = -1; while(i < N - 1) { if(samePos != -1) { if(第samePos个人和第i个人都说对方是好人) { i++; sameNum++; if(sameNum > N/2)//超过一半,肯定都是好人 { return people[samePos]; } } 最后要吗剩下一个好人,要吗剩下一串好人,复杂度为o(n) ,最快n/2,最慢n.写的不太严密,请大家指正. |
-- 作者:天涯客 -- 发布时间:7/3/2006 11:54:00 PM -- 我的想法,前提:被选出的人可以被一直重复选出; :如果N为偶数,所以至少有N/2个好人,取整 |好人-坏人|>=1(实际N为偶数的时候: |好人-坏人|>=2 );好人肯定说真话,保证了结论的正确性 >=50%, 任选A,所有人评A,比较结论,评出的结果,X:好人,Y:坏人,A=X>Y?好人:坏人; :同样的道理,N为奇数,有一样的结果。存在边界的情况:好人比坏人只多一人,X==Y;说明A为好人人。因为就算坏人都说假话,起码也有一半的真话。 所以整个算法的复杂度为 0(N). 请各位赐教! |
-- 作者:DavidPotter -- 发布时间:7/4/2006 4:18:00 PM -- l来去如风的思路不错:与查找众数的方法一样,通过不断的除去坏人与好人来利用好人超过半数的条件:如果有一个人说对方是坏人,那么两人种至少有一个坏人,可以同时排除,剩下的人照样满足条件好人站半树以上,再在剩下的人中找好人。 楼上(天涯客)的可能没有看清楚要找出好人的要求。如果A是外人的话,那么你的评选还要继续下去。 |
-- 作者:gln -- 发布时间:7/23/2006 8:55:00 PM -- 照来去如风的思路:如果两个人都说对方是好人,那么有两种可能,要吗都是好人,要吗都是坏人. 在此基础上,可以把这些人分为两组,A和B; a是A组的,a和x都说对方是好人,把x加到A组,否则加到B组,,哪一组的人数先过半数了,这组就是好人,另外一组就是坏人了. 时间复杂度o(n),最快n/2,最慢n..
|
-- 作者:cschentao -- 发布时间:8/8/2006 9:33:00 PM -- 其实firstwai几乎谈到重点了,来去如风的分析有问题。。明天得闲写下,哈哈 |
-- 作者:yooga -- 发布时间:7/23/2007 4:33:00 PM -- [原创] 最慢是[n/2] + 1 最快是[n/2] |
-- 作者:chenminyi -- 发布时间:8/27/2007 9:59:00 AM -- 这个好像就是算法导论上的课后习题,当时就没做出来。 |
-- 作者:algoman -- 发布时间:8/31/2007 12:18:00 PM -- 对于两个人都说对方是好人的情况,要么两个都是好人,要么两个都是坏人。因此可以如下操作 1)对于编号为1,2,...,n的n个人,分别按(1,2),(3,4)...这样配对(当n为奇数时有一人剩余,此人暂放一边),然后选出所有同时说对方是好人的配对。 2)若没有这样的配对.则那么由于超过一半为好人,此时所有配对均为好人与坏人配对.进而n必为奇数,且刚才配对时剩下的那个人必为好人.完毕 3)若至少有一个这样的配对,则从所有这样的配对中各抽出一个人,连同刚才可能剩下的那个人,重新组成序列 1,2,...,m(m<=ceil(n/2)).在这个新序列中超过一半为好人.则对此序列重新跳到步骤1)进行筛选 以上算法最快为O(1),最慢为O(log n) |
-- 作者:viperchenxi -- 发布时间:9/3/2007 10:57:00 AM -- 哈哈,有意思啊,思考一下 |
-- 作者:gracefullee -- 发布时间:9/10/2007 10:21:00 AM -- 也有可能死循环啊! 好人101个,坏人100个 如果100个好人配对 100个坏人配对,坏人全部说谎话! 那么就陷入了死循环 |
-- 作者:algoman -- 发布时间:9/15/2007 11:41:00 AM -- 这时就应该从这100个配对中各选出1人,连同剩余的那个好人,构成新的序列重复刚才的算法。新的序列中有51个好人和50个坏人 |
-- 作者:charloco -- 发布时间:9/20/2007 11:55:00 PM -- 先拿出一个人依次与其他人组合,如果他被认为是坏人或好人的次数大于一半,那么他就是坏人(好人)。如果第一个人就被半数以上的人认为是好人,那么他就是好人。时间复杂度为O(n). 最坏的情况是每次挑选的人都是坏人,其他人又都指认他是坏人,这样每一次只能排除一个坏人,时间复杂度为n*k-k*(k+1)/2,应该为O(n^2) |
-- 作者:woofang -- 发布时间:12/2/2007 2:32:00 AM -- google 面试题 http://www.woofang.com/google.htm |
-- 作者:snyyh -- 发布时间:12/10/2007 9:11:00 AM -- 二楼不对 |
-- 作者:affe -- 发布时间:12/14/2007 4:44:00 AM -- 第一步: 有两排凳子两两相对 a1,...,an b1,...,bn 如果有2n个人,就随便坐。如果有2n+1个人就,先挑一个站一边。 第二步: 第三步:
|
-- 作者:affe -- 发布时间:12/14/2007 4:52:00 AM -- 最坏情况是:成对坏人,连续出现,并且两人还都说的一样 @:好人 #:坏人 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 a @ @ # # # # # # # @ @ @ @ @ @ b @ @ # # # # # # # @ @ @ @ @ @ 改进的方法是在第二步最后加以个随即排序,但要保持ai 和bi相对的人始终相对,比如
[此贴子已经被作者于2007-12-14 5:30:55编辑过]
|
-- 作者:yan110 -- 发布时间:12/29/2007 1:48:00 PM -- 我不会写~~ |
-- 作者:冯诺依曼 -- 发布时间:1/5/2008 6:24:00 PM -- 考,楼上的全是高人! |
W 3 C h i n a ( since 2003 ) 旗 下 站 点 苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》 |
121.094ms |