229. 求众数 II

题目描述

给定一个大小为 n 的数组,找出其中所有出现超过 ⌊ n/3 ⌋ 次的元素。说明: 要求算法的时间复杂度为 O(n),空间复杂度为 O(1)。
示例 1:
输入: [3,2,3]
输出: [3]
示例 2:
输入: [1,1,1,3,3,2,2,2]
输出: [1,2]
提示1:
How many majority elements could it possibly have?
Do you have a better hint? Suggest it!

思路

两道众数题,解法的核心思想是:去掉两个不同的数(求大于⌊n/2⌋的元素)或者三个不同的数(求超过⌊n/3⌋次的元素)是不会改变最终要求的结果众数的
A,B,C
需要注意的是,这里的抵消需要一起进行,完成一次抵消操作一定去除的是三个完全不同的数,如果不满足这个条件,是不会触发抵消操作的
这种解法的正确性我们依然可以按照反证法进行论证

代码实现

class Solution {
public:
    vector<int> majorityElement(vector<int>& nums) {

        int n = nums.size();
        vector<int> ret;
        if(n == 0)
            return ret;
        int x = -1;
        int cnt1 = 0;
        int y = -1;
        int cnt2 = 0;
        for(int i = 0;i < n;i++)//流式处理
        {
            //num[i]是否分配给x
            if((cnt1==0 && (cnt2==0 || nums[i]!=y)) || (cnt1!=0 && nums[i]==x))//只能分配给x
            {
                x = nums[i];
                cnt1++;
                continue;
            }
            //程序到达这里,说明针对本轮的新样本num[i],x不满足计数值增加的条件
            //num[i]是否分配给y
            if((cnt2==0 && (cnt1==0 || nums[i]!=x)) || (cnt2!=0 && nums[i]==y))//只能分配给y
            {
                y = nums[i];
                cnt2++;
                continue;
            }
            //程序到达这里,说明针对本轮的新样本num[i],y不满足计数值增加的条件
            
            //到达这里说明num[i]既不能分配给x,也不能分配给y,只能独立成为一个实体,
            //与x,y,num[i]这三个不同的数发生抵消,去掉
            cnt1--;
            cnt2--;
            
        } 
        if(cnt1)
        {
            int cnt = 0;
            for(int i = 0;i < n;i++)
            {
                if(nums[i] == x)
                    cnt++;
            }
            if(cnt > n/3)
                ret.push_back(x);
        }
        if(cnt2)
        {
            int cnt = 0;
            for(int i = 0;i < n;i++)
            {
                if(nums[i] == y)
                    cnt++;
            }
            if(cnt > n/3)
                ret.push_back(y);
        }
        return ret;
        
    }
};

posted on 2021-07-18 12:11  朴素贝叶斯  阅读(48)  评论(0编辑  收藏  举报

导航