Boyer-Moore 投票算法(leetcode NO.169)

博客探讨了Boyer-Moore投票算法在解决多数元素问题中的应用。通过分析算法逻辑,解释了为何即使初始candidate不是多数元素,也会在后续过程中被正确识别。通过实例说明,即使在元素分布不均匀的情况下,算法最终也能找到出现次数超过n/2的多数元素。同时指出,若多数元素不存在,需要二次遍历确认。关键词聚焦于算法、多数元素、投票策略和数组处理。
摘要由CSDN通过智能技术生成

169、多数元素这道题的官方题解有一种算法个人感觉比较有趣,就是标题写的Boyer-Moore 投票算法。但是感觉官方没把这个算法讲清楚。所以我整合了一下各位评论区和题解区大佬的发言,讲讲这个算法。

对这题利用投票算法解题的分析可以看看官方题解和这位大佬的博客。其实都讲的挺好但是还是比较抽象。
我在看官方题解的时候看到一位大佬的评论:

如果候选人不是maj 则 maj,会和其他非候选人一起反对 会反对候选人,所以候选人一定会下台(maj==0时发生换届选举)
如果候选人是maj , 则maj 会支持自己,其他候选人会反对,同样因为maj 票数超过一半,所以maj 一定会成功当选

什么意思呢?我第一次看这个方法的题解,就在想如果第一次选到的candidate不是多数元素怎么办,看到这条评论我懂了。
如果我们选到的candidate不是多数元素,那么一定会在某一处被非candidate反对下台,为什么?因为非candidate里有握有半数以上选票的多数元素。
我们用一个最极端的例子来具象化这一想法:

[1,1,1,1,0,0,0,0,0]

按照投票算法的思路,我们一开始选择的candidate为1,就算它前期积累非常多的选票,等着它的也是至少多一票的反对票,因为它不是多数元素。
那后来我又想,为什么会在count重新变为0的时候替换candidate,意思就是为什么能够分出这样一些组合。那我们其实不要禁锢在究竟是什么数这样的思想上,把这些数分成两堆,一堆是多数元素,一堆不是多数元素,就拿官方题解中的例子来说明:

[7, 7, 5, 7, 5, 1, 5, 7, 5, 5, 7, 7 ,7, 7, 7, 7]
很显然多数元素为7
------------------------------------------------------>
[5, 1, 5, 5, 5, 5 , 7, 7, 7, 7, 7, 7, | 7, 7, 7, 7]

分成这样两波,就对应了上面的说法:如果一开始没有选到candidate多数元素,就算它前期积累非常多的选票,等着它的也是至少多一票的反对票。
那么当当前的candidate(候选人)被反对下台之后,就可以选取新的candidate,继续进行投票。知道找出支持票多的候选人(即多数元素)。那么把下属例子打乱,就会产生多处候选人被反对下台的情况,就算这一分块里是多数元素被反对下台了,也不可能影响宏观上多数元素票数更多的事实。在所有的反对票(非多数元素)都被相同数量的支持票(多数元素)消耗后,最后candidate一定会选到多数元素。每一分块开始都重置candidate并不是为了选出每一分块的多数元素,而是为了选到最后胜出的多数元素。

[5, 1, 5, 5, 5, 5, 7, 7, 7, 7, 7, 7, | 7, 7, 7, 7]

上述思路值适用于像多数元素这样明确表示多数元素一定存在的情况。若多数元素可能不存在,比如:

[5, 1, 5, 5, 5, 5, 7, 7, 7, 7, 7, 7]

那么最后得到的结果就会是5。解决方法就是拿着当前得出的值进行二次遍历,统计该数在数组中出现的次数,看是否大于 ⌊ n/2 ⌋ 。

还有一个就是,多数元素这道题里的多数元素指的是在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素而不是出现次数最多的数,就像上面的例子,7虽然不是出现次数大于 ⌊ n/2 ⌋ 的元素,但(在这儿停顿)是出现次数最多的数,能不能用投票算法呢?

Boyer-Moore投票法是一种用于查找元素序列中的众数的算法,它具有线性时间复杂度和常数级空间复杂度。该算法由Robert S. Boyer和J Strother Moore命名,是一种典型的流算法。\[1\] Boyer-Moore投票法分为两个阶段:抵消阶段和计数阶段。在抵消阶段,两个不同的候选人进行对抗,并同时抵消各自的一张票。如果两个候选人相同,则累加可抵消的次数。在计数阶段,如果抵消阶段最后得到的抵消计数不为0,那么这个候选人有可能超过一半的票数。为了验证这一点,需要遍历一次元素序列,统计票数,才能确定最终的众数。\[2\] 更多关于Boyer-Moore投票法的详细信息可以参考\[3\]。 #### 引用[.reference_title] - *1* *3* [摩尔投票算法](https://blog.csdn.net/qq_17550379/article/details/83818965)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [摩尔(Boyer-Moore)投票法](https://blog.csdn.net/qq_40692109/article/details/104805815)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值