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;
}
};