leetcode打卡--moore投票法的运用详解

Posted C_YCBX Py_YYDS

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了leetcode打卡--moore投票法的运用详解相关的知识,希望对你有一定的参考价值。

题目

摩尔投票概述

摩尔投票需要经过以下两个阶段:

  1. 抵消阶段
  2. 计数阶段

抵消阶段:两个不同投票进行对坑,并且同时抵消掉各一张票,如果两个投票相同,则累加可抵消的次数。

计数阶段:在抵消阶段最后得到的抵消计数只要不为 0,那这个候选人是有可能超过一半的票数的,为了验证,则需要遍历一次,统计票数,才可确定。

举个例子:在任意多的候选人中,选出票数超过⌊ 1/3 ⌋的候选人。

我们可以这样理解,假设投票是这样的 [A, B, C, A, A, B, C],ABC 是指三个候选人。

第 1 张票,第 2 张票和第3张票进行对坑,如果票都不同,则互相抵消掉;

第 4 张票,第 5 张票和第 6 张票进行对坑,如果有部分相同,则累计增加他们的可抵消票数,如 [A, 2] 和 [B, 1];

接着将 [A, 2] 和 [B, 1] 与第 7 张票进行对坑,如果票都没匹配上,则互相抵消掉,变成 [A, 1] 和 `[B, 0] 。

看下面动画,就知道什么回事了。

  1. 最多选取一个代表的过程:
  2. 最多选取两个代表的过程

动画转自leetcode。

总结归纳:

如果至多选一个代表,那他的票数至少要超过一半(⌊ 1/2 ⌋)的票数;

如果至多选两个代表,那他们的票数至少要超过 ⌊ 1/3 ⌋ 的票数;

如果至多选m个代表,那他们的票数至少要超过 ⌊ 1/(m+1) ⌋ 的票数。

所以以后碰到这样的问题,而且要求达到线性的时间复杂度以及常量级的空间复杂度,直接套上摩尔投票法。

解题过程

  • 由于是选出两个代表的问题,也就是选出票数超过 1/3 的个数。

有以下两种做法:

  1. 哈希表
  2. 摩尔投票法

解题代码

哈希表法

class Solution {
public:
    vector<int> majorityElement(vector<int>& nums) {
        unordered_map<int,int>check;
        int c = nums.size()/3;
        unordered_set<int>tt;
        for(auto&& t : nums){
            check[t]++;
            if(check[t]>c){
                tt.insert(t);
            }
        }
        vector<int>res(tt.begin(),tt.end());
    return res;
    }
};

摩尔投票法

class Solution {
public:
    vector<int> majorityElement(vector<int>& nums) {
        int n = nums.size();
        vector<int>res;
        if(n<3){
            unordered_set<int> t(nums.begin(),nums.end());
            return vector<int>(t.begin(),t.end());
        }
        int candidate1 = nums[0],candidate2 = nums[1],cnt1 = 0,cnt2 = 0;
        for(auto&& t:nums){//投票过程
            if(t==candidate1){
                cnt1++;
                continue;
            }
            if(t==candidate2){
                cnt2++;
                continue;
            }
            if(cnt1==0){
                candidate1 = t;
                cnt1++;
                continue;
            }
            if(cnt2==0){
                candidate2 = t;
                cnt2++;
                continue;
            }
            cnt1--;
            cnt2--;
        }
    int _cnt1 = 0,_cnt2 = 0;
    for(auto&&t:nums){_cnt1 += candidate1==t?1:0;}//计数过程
    for(auto&&t:nums){_cnt2 += candidate2==t?1:0;}
    if(_cnt1>n/3)res.push_back(candidate1);
    if(_cnt2>n/3){
        if(res.empty())
            res.push_back(candidate2);
        else{
            if(candidate2!=candidate1)
                res.push_back(candidate2);
        }
    }
    return res;
    }
};

以上是关于leetcode打卡--moore投票法的运用详解的主要内容,如果未能解决你的问题,请参考以下文章

算法-多数投票算法(Boyer-Moore Voting Algorithm)及推广

算法整理:Boyer-Moore 投票算法

229. 求众数 II摩尔投票法的扩展

Task 待学习内容Moore majority vote algorithm(摩尔投票算法)

Boyer–Moore Majority Vote Algorithm摩尔投票法,众数算法,Java

Boyer–Moore Majority Vote Algorithm摩尔投票法,众数算法,Java