方法一:Map或者计数数组
public int majorityElement(int[] a) {
int n = a.length;
Map<Integer,Integer> map = new HashMap<>();
for(int x:a){
map.put(x,1+map.getOrDefault(x,0));
}
for(int x:map.keySet()){
if(map.get(x)>n/2){
return x;
}
}
return -666;
}
方法二:摩尔投票
public int majorityElement(int[] a) {
int candi = -666;//候选
int cnt = 0;//对当前候选计数,但是不是全程计数,而是除抵消外的计数
for(int x:a){
if(cnt == 0){//如果cnt=0,说明当前candi被别的不同元素消耗完了,candi要更新为新的人选了,也就是当前遍历的元素
candi = x;
}
if(x!=candi){
cnt--;
}else{
cnt++;
}
}
return candi;
}
总结
方法一最简单暴力。方法二时间O(n),空间O(1),利用一个技巧,如果遇到2个不同的数,就相当于他们抵消了,不用对他们计数,因为他们两者有一个是最终答案的话,也就是如果出现了总长的一半以上话,最后一定不会被抵消空,一定会剩下>1个,所以
- 可以用一个变量candi表示当前的结果候选
- 如果遇到和他相等的,就计数,不相等的就抵消,即计数-1
- 如果发现计数为0,说明开始的候选此时被抵消完了,直接更新候选,最后candi保留的一定是没有被抵消的