leetcode229229. 求眾數 II(hash 摩爾投票)
阿新 • • 發佈:2021-10-22
連結:https://leetcode-cn.com/problems/majority-element-ii/
題目
給定一個大小為n的整數陣列,找出其中所有出現超過⌊ n/3 ⌋次的元素。
用例
示例1:
輸入:[3,2,3]
輸出:[3]
示例 2:
輸入:nums = [1]
輸出:[1]
示例 3:
輸入:[1,1,1,3,3,2,2,2]
輸出:[1,2]
提示:
1 <= nums.length <= 5 * 104
-109 <= nums[i] <= 109
進階:嘗試設計時間複雜度為 O(n)、空間複雜度為 O(1)的演算法解決此問題。
思路
方法一
樸素hash表篩選
用雜湊表記錄每一個數字出現的頻率
class Solution { public: vector<int> majorityElement(vector<int>& nums) { int n=nums.size()/3; unordered_map<int,int>mp; vector<int>ans; for(auto a:nums){ mp[a]++; } for(auto b:mp){ if(b.second>n) ans.push_back(b.first); } return ans; } };
方法二
摩爾投票法
關聯leetcode169.多數元素(連結:https://leetcode-cn.com/problems/majority-element/)
對於僅存在一個出現次數 大於 ⌊ n/2 ⌋ 的元素
可以對設定摩爾投票
設定e1記錄元素 設定c1記錄投票數量
遍歷陣列 當投票數c1>0且當前nums[i]與記錄元素e1相等時 c1++
當c1==0時,e1變化為nums[i],且c1++
其實就是一個消消樂思想 每次把兩個不同的數字刪去
class Solution { public: int majorityElement(vector<int>& nums) { int n=nums.size(); int e1=0,v1=0; for(auto num :nums){ if(v1==0){ e1=num; v1++; }else if(e1==num){ v1++; }else{ v1--; } } return e1; } };
本題求眾數 也可以用這個思想
出現次數超過 ⌊ n/3 ⌋ 次的元素,在陣列中至多隻能存在2個
我們可以每次消除三個不同的數,來獲取候選答案(候選答案為出現頻率前2的元素,但其中一個不一定滿足條件)
最後對候選答案進行驗證 判定是否大於 ⌊ n/3 ⌋ 次
class Solution {
public:
vector<int> majorityElement(vector<int>& nums) {
int n=nums.size()/3;
int e1=0,e2=0,c1=0,c2=0;
for(auto a:nums){
if(a==e1&&c1>0){
c1++;
}else if(a==e2&&c2>0){
c2++;
}else if(c1==0){
e1=a;
++c1;
}else if(c2==0){
e2=a;
++c2;
}else{
c1--;
c2--;
}
}
c1=0;
c2=0;
for(auto a:nums){
if(a==e1)
c1++;
if(a==e2)
c2++;
}
vector<int>ans;
if(c1>n)
ans.push_back(e1);
if(c2>n)
{
if(e1!=e2)
ans.push_back(e2);
}
return ans;
}
};