ans1. 先对数组排序
1.1
class Solution {
public:
int majorityElement(vector<int>& nums) {
int numssize = nums.size();
sort(nums.begin(),nums.end());
int i = 0;
if(numssize == 1){
return nums[0];
}
while(i < numssize){
int count = 1;
while(i < numssize && nums[i] == nums[i+1]){
count++;
i++;
if(count > numssize/2){
return nums[i];
}
}
i++;
}
return 1;
}
};
1.2 优化:多数元素出现次数大于n/2 ,故中点元素必是多数元素
class Solution {
public:
int majorityElement(vector<int>& nums) {
int numssize = nums.size();
sort(nums.begin(),nums.end());
return nums[numssize/2];
}
};
ans2. 摩尔投票法
题目中我们需要查找的数字超过数组长度的一半,也就是说,要查找的数字target的个数会超过其他数字个数。
假设不同数字相互抵消,那么最后剩下的数字,就是我们要找的多数元素。
我们可以把这个过程打个比方,比如现在多军对峙,假设阵营A士兵人数比其他方的人数都多,阵营A士兵能以一杀一,那么只要阵营A士兵不杀自己人(相同数字),去杀不同阵营的人(不同数字),那么最后剩下的那些士兵,就是阵营A的士兵。
因此我们可以假设数组的第一个数字为target,然后遍历数组,我们尝试用计数cnt模拟这个抵消的过程,规则如下:1)当数组中的元素与假设的target不相等时,计数cnt减1,即模拟不同数字相互抵消;
2)假设数组中的元素与假设的target相等时,计数cnt加1;
3)当计数cnt等于0时,说明在当前遍历到的数组元素中,当前假设的target与其他数字相互抵消(个数相同),所以我们重新假设下一个遍历的数组元素为target,继续上面过程。
4)当遍历完数组后,target为所求数字。
本引用作者:ni-wo-shan-dian-zi-xiang-feng-3e
来源:力扣
class Solution {
public:
int majorityElement(vector<int>& nums) {
int count = 0,result = nums[0];
int n = nums.size();
for(int i = 0;i < n;++i){
if(count == 0) result = nums[i];
if(result == nums[i]){
count++;
}else{
count--;
}
}
return result;
}
};
ans3. 随机法
大于1/2的概率能猜到众数,可以随机假设一个数为众数,然后验证。
理论上期望的时间复杂度为O(n),空间复杂度为O(1)
class Solution {
public:
int majorityElement(vector<int>& nums) {
while (true) {
int candidate = nums[rand() % nums.size()];
int count = 0;
for (int num : nums)
if (num == candidate)
++count;
if (count > nums.size() / 2)
return candidate;
}
return -1;
}
};