Boyer-Moore投票算法(图解)(Leetcode每日一题-排序)(2023.4.15)

C++_vector操作

vector<int> a

a.size()//容器a内元素个数
sort(a.begin(),a,end())//升序排序a
a.push_back(i)//向容器加入元素
a.pop_back()//弹出容器顶部元素
a.empty()//判空

169. 多数元素

给定一个大小为 n 的数组 nums ,返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。

你可以假设数组是非空的,并且给定的数组总是存在多数元素。

示例 1:

输入:nums = [3,2,3]
输出:3

示例 2:

输入:nums = [2,2,1,1,1,2,2]
输出:2

排序+查找

class Solution {
public:
    int majorityElement(vector<int>& nums) {
        long long int n = nums.size();
        long long int p = n/2;
        long long int i,j,k = 0;
   
        sort(nums.begin(),nums.end());//排序
       
        for(i = 0;i < n;)
        {
            k = 0;
            for(j = i;j < n &&nums[j] == nums[i];j++)
            k++;
            if(k > p)
            break;
    
            i = j;
        }
        return nums[i];
    }
};

排序+规律

class Solution {
public:
    int majorityElement(vector<int>& nums) {
        sort(nums.begin(), nums.end());
        return nums[nums.size() / 2];
    }
};

//作者:力扣官方题解
//链接:https://leetcode.cn/problems/majority-//element/solutions/146074/duo-shu-yuan-su-by-leetcode-solution/
//来源:力扣(LeetCode)
//著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

随机化

class Solution {
public:
    int majorityElement(vector<int>& nums) {
        while (true) {
            int candidate = nums[rand() % nums.size()];
            int count = 0;
            for (int num : nums)
                if (num == candidate)
                    ++count;
            if (count > nums.size() / 2)
                return candidate;
        }
        return -1;
    }
};

//作者:力扣官方题解
//链接:https://leetcode.cn/problems/majority-element/solutions/146074/duo-shu-yuan-su-by-leetcode-solution/
//来源:力扣(LeetCode)
//著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

Boyer-Moore 投票算法
在这里插入图片描述

比如:
【1,1,2,2,2】
在这里插入图片描述

public int majorityElement(int[] nums) {
    int winner = nums[0];
    int count = 1;
    for (int i = 1; i < nums.length; i++) {
        if (winner == nums[i]) {
            count++;
        } else if (count == 0) {
            winner = nums[i];
            count++;
        } else {
            count--;
        }
    }
    return winner;
}

Boyer-Moore 投票算法进阶

229. 多数元素 II

给定一个大小为 n 的整数数组,找出其中所有出现超过 ⌊ n/3 ⌋ 次的元素。

示例 1:

输入:nums = [3,2,3]
输出:[3]

示例 2:

输入:nums = [1]
输出:[1]

示例 3:

输入:nums = [1,2]
输出:[1,2]

在这里插入图片描述
摩尔投票法分为两个阶段:抵消阶段和计数阶段

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

计数阶段:在抵消阶段最后得到的抵消计数只要不为 0,那这个候选人是有可能超过一半的票数的,但这不意味着这个候选人的票数一定能超过一半,例如 [A, B, C] 的抵消阶段,最后得到的结果是 [C,1],C 候选人的票数也未能超过一半的票数。为了验证,则需要遍历一次,统计票数,才可确定。

在这里插入图片描述
绿色的小人去选出在三个人中选出红色的候选人
三个小人中产生最多两个候选人,即最多有两个人在数组中出现的次数大于1/3,必定有一个人的出现次数小于1/3.
在投票环节中:
(1)三个人都有一票等于,三个人都没有票,两个候选人票数减1
(2)一个候选人有票,另外一个没有,则此时被投票的当候选人

比如:ABBCBCAA
最开始投票给了A,B两人:
cand1 = A count1 = 1
cand2 = B count2 = 1
接下来又是B:
cand1 = A count1 = 1
cand2 = B count2 = 2
接下来是C:
cand1 = A count1 = 0//三个人都有一票等于,三个人都没有票,两个候选人票数减1
cand2 = B count2 = 1
接下来B:
cand1 = A count1 = 0
cand2 = B count2 = 2
C://A没票了,C当候选人
cand1 = C count1 = 1
cand2 = B count2 = 2
A:
cand1 = C count1 = 0
cand2 = B count2 = 1
A:
cand1 = A count1 = 1
cand2 = B count2 = 1

代码如下:

class Solution {
public:
    vector<int> majorityElement(vector<int>& nums) {
       vector<int> a;
       //投票阶段
       //选出候选人
        int i,n = nums.size();
       
       int cand1 = 0,cand2 = 0;//候选人
       int count1 = 0,count2 = 0;//此候选人所得票数
      
       for(i = 0;i < n;i++)
       {
         if(nums[i] == cand1)
         count1 ++;
         else if(nums[i] == cand2)
         count2 ++;
         else if(count1 != 0 && count2 != 0)//三个人都有一票
         {
          count1--;
          count2--;
         }
         else if(count1 == 0)//cand1没有票
         {
           cand1 = nums[i];
           count1 = 1;
         }
         else if(count2 == 0)//cand2没有票
         {
           cand2 = nums[i];
           count2 = 1;
         }
        
       }
       //计数阶段
       int q = n/3;
       int cnt1 = 0,cnt2 = 0;
        for(i = 0;i < n;i++)
          if(nums[i] == cand1)
          cnt1++;
          else if(nums[i] == cand2)
          cnt2++;

       
       if(count1!=0&&cnt1 > q)
       a.push_back(cand1);
       if(count2!=0&&cnt2 > q)
       a.push_back(cand2);

       return a;
    }
};

如果最开始把cand1 = nums[0],cand2 = nums[1]
[3,3,4]会没法通过,因为两个候选人重复了

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
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 ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值