摩尔投票

绝地灬酷狼 2022-12-29 04:42 356阅读 0赞

摩尔投票

问题背景

在一个大厅中,每位票民手中都有一张票他可以给自己喜欢的候选人偷一票,我们现在已知每个票民的投票结果。
问:如何通过一次遍历找到票数超过一半的候选人。

解决方案

方案一

我们可以使用一个容器对每位候选人的票数进行计数,然后查看每位候选人的总票数,就可以找到票数超过一半的候选人。
在具体代码实现的时候,c++中可以使用一个map容器维护每位候选人的票数。
具体时间复杂度为O(n),空间复杂度为O(m),m为候选人的个数。

方案二

我们可以使用摩尔投票法求解。
摩尔投票法,解决的问题是如何在任意多的候选人中,选出票数超过一半的那个人。注意,是超出一半票数的那个人。
假设投票是这样的,[A, C, A, A, B],ABC 是指三个候选人。
第一张票与第二张票进行对坑,如果票不同则互相抵消掉;
接着第三票与第四票进行对坑,如果票相同,则增加这个候选人的可抵消票数;
这个候选人拿着可抵消票数与第五张票对坑,如果票不同,则互相抵消掉,即候选人的可抵消票数 -1。

我们可以这样思考,我们可以选择每次选择两个人碰一下,如果他们的候选人不同,那么这两个人打一架然后出局,然后再选择两个人。如果两个人候选人是一伙的,那么他们在随机找一个人,如果不跟他们同一伙,那么他们两个人中一个人去跟那个人打架然后抵消掉即可。依次类推,最后剩下的人一定是一伙的,然后我们检测一下他们投的候选人是不是票数过半即可。如果最后没剩人,说明没有候选人票数过半。
关于应用,可以参考leetcode169

代码实现:

  1. class Solution {
  2. public:
  3. int majorityElement(vector<int>& nums) {
  4. int n=nums.size();
  5. int n1=0,nnum=0;
  6. for(auto &a:nums){
  7. if(nnum==0) {
  8. //此时没有选中人
  9. n1=a;
  10. nnum++;
  11. }
  12. else if(a==n1) nnum++;
  13. else nnum--;
  14. }
  15. //题目说了有答案所以省去检测环节
  16. return n1;
  17. }
  18. };

明天将对该算法的进阶进行叙述。晚安!!!

发表评论

表情:
评论列表 (有 0 条评论,356人围观)

还没有评论,来说两句吧...

相关阅读

    相关 投票

    背景: leetcode 169题求一个数组中,出现次数大于 n/2;的元素 如果在一个遍历中解决这个问题?? 答案就是摩尔投票法。 摩尔投票法:用一个计数器,每次当计

    相关 投票

    提问: 给定一个int型数组,找出该数组中出现次数大于数组长度一半的int值。 解决方案: 遍历该数组,统计每个int值出现次数,再遍历该数组,找出出现次数大于数组长度一半的

    相关 投票

    摩尔投票 问题背景 在一个大厅中,每位票民手中都有一张票他可以给自己喜欢的候选人偷一票,我们现在已知每个票民的投票结果。 问:如何通过一次遍历找到票数超过一半的

    相关 8-1投票

    > 不同的数字进行一对一“火并”(原理不再赘叙), > 如果存在众数,“火并”之后留下了的一定是,最后还需要进行验证。 先上模板:         ![watermar