leetcode229229. 求众数 II(hash 摩尔投票)
链接: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;
}
};

浙公网安备 33010602011771号