[LeetCode]Majority Element

题意: 找出一个数组中的主要元素,主要元素为出现次数大于[n/2]的元, 当然最笨的方法就是暴力,没式不知道时间行不行
思路1: 遍历数组,统计每个元素出现的次数,用HashMap统计每个元素出现的次数 时间复杂度O(N),空间复杂度 O(N)
代码1:

public class Solution {
       public int majorityElement(int[] num) {
        int majority = 0, currCount;
        int major = (int) Math.floor( num.length*1.0 / 2 );
        if(num.length == 1) return num[0];
        Map<Integer, Integer> m = new HashMap<Integer, Integer>();
        for(int i = 0; i< num.length; ++i){
            if(m.containsKey(num[i])){
                currCount = m.get(num[i]) + 1;
                if(currCount > major) return num[i];
                m.put(num[i], currCount);
            }else m.put(num[i],1);
        }

        return majority;
    }

}

思路2:直接排序,然后找到中间的那个数就可以了,时间复杂度 O(N*log(N))
代码2:

    public int majorityElement(int[] num) {//排序
        int majority = 0, currCount;
        int major = (int) Math.floor( num.length*1.0 / 2 );
        if(num.length == 1) return num[0];

        Arrays.sort(num);

        return num[num.length/2];
    }


思路3:Moore voting algorithm ,维护一个candidate 以及他的计数 counter// 算法复杂度 O(N)
代码3:

    public int majorityElement(int[] num) {//摩尔投票算法
        int majority = 0, currCounter = 0, candidate = 0;
        int minCounter = (int) Math.floor( num.length*1.0 / 2 );
        if(num.length == 1) return num[0];

        for(int i = 0; i < num.length; ++i){
            if(currCounter == 0){
                candidate = num[i];
                currCounter ++;
            }else {
                if(candidate == num[i]){
                    currCounter ++;
                }
                else currCounter --;
            }
            if(currCounter > minCounter)return candidate;
        }
        return candidate;
    }

还有一种官方的解法:时间复杂度: O(n) — 位操作法: 我们需要32次迭代, 每一次计算所有n个数的第i位的1的个数。由于众数一定存在,那么或者1的个数 > 0的个数 或者反过来(但绝不会相同)。 众数的第i位一定是计数较多数字。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值