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

进阶:尝试设计时间复杂度为 O(n)、空间复杂度为 O(1)的算法解决此问题

题解:摩尔投票法选出出现频数最多的值。O(N)时间,O(1)空间。
摩尔投票法分为两个阶段:抵消阶段和计数阶段。

抵消阶段: 两个不同投票进行对坑,并且同时抵消掉各一张票,如果两个投票相同,则累加可抵消的次数;
计数阶段: 在抵消阶段最后得到的抵消计数只要不为 0,那这个候选人是有可能超过一半的票数的,为了验证,则需要遍历一次,统计票数,才可确定。

升级的摩尔投票在于最终的候选者(众数)有一个或者两个;因为题目要求了超过N/3,如果有三个候选人。那么不会有大于N/3的候选者。

class Solution {
public:
    vector<int> majorityElement(vector<int>& nums) {
        vector<int> res;
        if (nums.size() == 0) return res;
        // 初始化两个候选人candidate,和他们的计票
        int cand1 = nums[0], count1 = 0;
        int cand2 = nums[0], count2 = 0;

        // 摩尔投票法,分为两个阶段:抵消阶段和计数阶段
        // 抵消阶段
        for (int i=0;i<nums.size();i++) {
            // 投票
            if (cand1 == nums[i]) {
                count1++;
                continue;
            }
            if (cand2 == nums[i]) {
                count2++;
                continue;
            }

            // 第1个候选人抵消
            if (count1 == 0) {
                cand1 =nums[i];
                count1++;
                continue;
            }
            // 第2个候选人抵消
            if (count2 == 0) {
                cand2 = nums[i];
                count2++;
                continue;
            }

            count1--;
            count2--;
        }

        // 计数阶段
        // 找到了两个候选人之后,需要确定票数是否满足大于 N/3
        count1 = 0;
        count2 = 0;
        for (int i=0;i<nums.size();i++)  {
            if (cand1 == nums[i]) count1++;
            else if (cand2 == nums[i]) count2++;
        }

        if (count1 > nums.size() / 3) res.push_back(cand1);
        if (count2 > nums.size() / 3) res.push_back(cand2);

        return res;

    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值