摩尔投票法
运用的是成对删除的思想:
假如有10个人参与投票,有的人投给A,有的人投给B,有的人投给C,当我们想要找出A、B、C谁得票最多时,
我们可以将两个不同的投票作为一对进行删除,直到不能再删时然后再查看结果中还剩下的投票就是得票最
多的那个
leetcode的运用:
求众数I
给定一个大小为 n 的数组,找到其中的众数。众数是指在数组中出现次数大于 ⌊ n/2 ⌋的元素你可以假 设数组是非空的,并且给定的数组总是存在众数。
class Solution {
public:
int majorityElement(vector<int>& nums) {
// 摩尔投票法;
int tar=nums[0], cnt=1;
for(int i=1;i<nums.size();i++){
if(nums[i]==tar)cnt++;
else{
cnt--;
if(!cnt){
tar=nums[i];
cnt=1;
}
}
}
return tar;
}
};
可以看出,大于n/2的数字一定是在成对删除剩下的那个数字
求众数II
给定一个大小为 n 的数组,找出其中所有出现超过 ⌊ n/3 ⌋ 次的元素。
public:
vector<int> majorityElement(vector<int>& nums) {
int size = nums.size();
vector<int> res;
if (size == 0) {
return res;
}
int a = 0, b = 0, cnt1 = 0, cnt2 = 0;
for (int num : nums) {
if (num == a) {
++cnt1;
} else if (num == b) {
++cnt2;
} else if (cnt1 == 0) {
a = num;
++cnt1;
} else if (cnt2 == 0) {
b = num;
++cnt2;
} else {
--cnt1;
--cnt2;
}
}
cnt1 = cnt2 = 0;
for (int num : nums) {
if (num == a) {
++cnt1;
} else if (num == b) {
++cnt2;
}
}
if (cnt1 > size / 3) {
res.push_back(a);
}
if (cnt2 > size / 3) {
res.push_back(b);
}
return res;
}
};
这次没有保证一定存在满足条件的数字,由此需要投票+验证
第一次循环找出的数字不一定是满足条件的数字,需要对可能数字计数判断。