题目:
题解:
- 摩尔投票法:由于众数的次数超过n/3,所以数组最多有两个众数(两个众数的次数大于2n/3)
代码如下:
class Solution {
public:
//题解1:暴力法
vector<int> majorityElement_1(vector<int>& nums) {
map<int,int> m;
int n=nums.size();
set<int> res;
for(int num:nums){
m[num]++;
if(m[num]>n/3)res.insert(num);
}
return vector<int> (res.begin(),res.end());
}
//题解2:摩尔投票法,由于众数的次数超过n/3,所以数组最多有两个众数(两个众数的次数大于2n/3)
vector<int> majorityElement(vector<int>& nums){
if(nums.empty())return {};
int A=nums[0],B=nums[0],countA=0,countB=0,n=nums.size();
//第一次遍历:找出两个可行的候选人
for(int num:nums){
//1、num和A或B相等,给A或B投票
if(A==num){countA++;continue;}
if(B==num){countB++;continue;}
//2、num和AB都不等且AB的票数都为0,那么重新更新A|B,也就是重新更新候选人
if(countA==0){A=num;countA++;continue;}
if(countB==0){B=num;countB++;continue;}
//3、num和AB都不等,且AB的票数都不为0,那么将它们的票数都减1
countA--;
countB--;
}
//第二次遍历,确定候选人
//上一轮遍历找出了两个候选人,但是这两个候选人是否均满足票数大于N/3仍然没法确定,需要重新遍历,确定票数
countA=0,countB=0;
for(int num:nums){
if(num==A)countA++;
else if(num==B)countB++;
}
vector<int> res;
if(countA>n/3)res.push_back(A);
if(countB>n/3)res.push_back(B);
return res;
}
};
补充:摩尔投票法模板(此众数的频率为n/2,同样可用于其他频率的)
#include <iostream>
#include <vector>
using namespace std;
int majorityElement(vector<int> nums)
{
int majority=-1,count=0;
//第一次遍历:选出候选人
for(int num:nums)
{
if(count==0){
majority=num;
count++;
}
else{
if(num==majority)count++;
else count--;
}
}
if(count<=0)return -1;
count=0;
//第二次遍历:确定候选人的票数是否满足
for(int num:nums){
if(num==majority)count++;
}
if(count>nums.size()/2)return majority;
else return -1;
}
int main()
{
vector<int> nums={1,0,3,2,2,2,2,2,6};
cout<<majorityElement(nums)<<endl;
system("pause");
}