![](https://img2020.cnblogs.com/blog/1517575/202101/1517575-20210121162327177-1920950270.png)
思路分析
大于数组长度的数字有多少个?
很明显只有一个.
因为如果有多个就矛盾了.
哈希表
哈希表的思路就很简单了,就是每个数的出现次数,然后找出超过一半的那个数.
cpp
class Solution {
public:
int majorityElement(vector<int>& nums) {
unordered_map<int,int> d;
for(auto x:nums)
if(d.count(x))d[x]+=1;
else d[x]=1;
int n = nums.size()/2;
for(unordered_map<int,int>::iterator i=d.begin();i!=d.end();i++)
if(i->second>n)return i->first;
return 0;
}
};
python
class Solution:
def majorityElement(self, nums: List[int]) -> int:
d = dict()
n = len(nums)//2
for x in nums:
if x not in d:d[x]=1
else: d[x]+=1
for k,v in d.items():
if v>n:return k
return 0
排序
排序就是超过一半数一点在中间位置.
cpp
class Solution {
public:
int majorityElement(vector<int>& nums) {
sort(nums.begin(),nums.end());
return nums[nums.size()/2];
}
};
python
class Solution:
def majorityElement(self, nums: List[int]) -> int:
nums.sort()
return nums[len(nums)//2]
摩尔投票
如何证明是对的?
用"消耗"的角度来看, 如果要消灭一个"众数",那么就必须要一个非"众数",那么最后"众数"肯定是有剩余的
value:
count:
遍历数组,
如果count=0,那么将value换为x
如果count!=0,
1) value!=x,则count--
2) value==x,则count++
最后的value就是答案
cpp
class Solution {
public:
int majorityElement(vector<int>& nums) {
int value,count=0;
for(auto x:nums){
if(!count)value=x,count=1;
else{
if(value==x)count++;
else count--;
}
}
return value;
}
};
python
class Solution:
def majorityElement(self, nums: List[int]) -> int:
value,count=None,0
for x in nums:
if not count:
value=x
count=1
else:
if x==value:count+=1
else: count-=1
return value
延申情景: 好人和坏人/好软件和坏软件
就是有超过n/2的都是好人,剩下都是坏人.
你可以询问每一个人,每个人都是知道直接和其他人的身份.
但是,好人会实话实说,坏人就不会实话实说,如何找出坏人?
从"消耗对"的角度来看,好人-坏人是一对的.
但是好人是一定比坏人多的,所以最后剩下的一定是好人
现在要把所有的坏蛋找出来.
value: 某人
count: 信任值
如果信任值为0,那么说明这个人就是坏人,就把这个人删除
然后从头开始,直到循环遍历结束.