LeetCode 169.多数元素

127 阅读1分钟

方法一: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保留的一定是没有被抵消的