LC229-求众数II

229. 求众数 II

法1:哈希暴力计数 时间复杂度 \(O(n)\) 空间复杂度 \(O(n)\)

class Solution {
public:
    vector<int> majorityElement(vector<int>& nums) {
        unordered_map<int,int>cnt;
        vector<int>res;
        int n = nums.size();
        for(auto &c : nums) cnt[c] ++;
        for(auto &[k, v] : cnt) if(v > n / 3) res.push_back(k);
        return res;
    }
};

法2:摩尔投票算法

link with LC-169 摩尔投票算法可以用于解决类似题中描述的n/k的问题,可以在\(O(nk)\)的时间复杂度,\(O(1)\)的空间复杂度下解决问题。对于k个数,则开 $r_1,r_2,r_3 .... ,r_k $,对应 \(c_1, c_2, c_3, ....,c_k\),做法类似 。

class Solution {
public:
    vector<int> majorityElement(vector<int>& nums) {
        int r1, r2, c1 = 0, c2 = 0, n = nums.size();  // r是当前的数,c是当前数的累计计数
        for(auto& x : nums){
            if(c1 && r1 == x) c1++;
            else if(c2 && r2 == x) c2++;
            else if(!c1) r1 = x, c1 = 1;
            else if(!c2) r2 = x, c2 = 1;
            else --c1, --c2; 
        }
        c1 = c2 = 0;
        vector<int>res;                               //最后判断两个数是否符合条件
        for(auto& x : nums) c1 += (r1 == x), c2 += (r2 == x);
        if(c1 > n / 3) res.push_back(r1); 
        if(r1 != r2 && c2 > n / 3) res.push_back(r2); //排除两个数一样的情况
        return res;
    }
};
posted @ 2021-07-09 21:43  Ivessas  阅读(99)  评论(0)    收藏  举报