多数元素

给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素。

你可以假设数组是非空的,并且给定的数组总是存在多数元素。

思路一:
自己的思路,估计也是最容易想到而且效率最低的。就是通过一个HashMap来存储每个key出现的次数。不过通过编写这个,我了解了Map的遍历方式。也就是通过遍历Map中的Entry来获取key和value。

  • 时间复杂度:O(n)。
  • 空间复杂度:O(n),因为使用哈希表。
class Solution {
    public int majorityElement(int[] nums) {
        HashMap<Integer,Integer> map = new HashMap<Integer,Integer>();
        for(int i:nums){
            if(map.containsKey(i)){
                int tmp = map.get(i);
                map.put(i,tmp+1);
            }else{
                map.put(i,1);
            }
        }
        Iterator<Map.Entry<Integer,Integer>> it = map.entrySet().iterator();
        while(it.hasNext()){
            Map.Entry<Integer,Integer> entry = it.next();
            if(entry.getValue()>nums.length/2){
                return entry.getKey();
            }
        }
        return 0;
    }
}

思路二:
先对数组进行排序,那么在下标为n/2的值就是众数。

  • 时间复杂度:O(nlogn)
  • 空间复杂度:O(1)或者O(n)。如果可以原地就是O(1),还要新建一个数组就是O(n)。
class Solution {
    public int majorityElement(int[] nums) {
        Arrays.sort(nums);
        return nums[nums.length/2];
    }
}

思路三:
分治法。每一个区间都会有一个众数,对于只有一个数字的区间,显然众数就是该数。将两个区间合并起来时,如果他们的众数相等,则该数依然为此大区间的众数,不等就要统计两个众数在这个区间内谁才是真的众数。(分治也就是先拆分成小的,再一个一个组合成大的)

  • 时间/空间复杂度均为O(nlogn)。
class Solution {
    public int majorityElement(int[] nums) {
        return getMajority(nums,0,nums.length-1);
    }
    public int getMajority(int[] nums,int left,int right){
        if(left==right)    return nums[left];
        int leftMajor = getMajority(nums,left,(left+right)/2);
        int rightMajor = getMajority(nums,(left+right)/2+1,right);
        if(leftMajor==rightMajor){
            return leftMajor;
        } else{
            int leftNum = numberInRange(nums,left,right,leftMajor);
            int rightNum = numberInRange(nums,left,right,rightMajor);
            return leftNum>rightNum?leftMajor:rightMajor;
        }
    }
    public int numberInRange(int[] nums,int left,int right,int num){
        int res = 0;
        for(int i=left;i<=right;i++){
            if(nums[i]==num){
                res++;
            }
        }
        return res;
    }
}

思路四:
Boyer-Moore 投票算法!!!
首先我们需要知道,众数的数量比其他数加起来还要多,所以可以采用这个方法:
设置一个数,命名为“候选众数”,为他设置一个计数器x。起初让它的值为数组的第一个数(x记为1),然后然后遍历,遇到一个候选众数就x++,遇到非候选众数就x–。如果x=0了,就废弃掉这个候选众数,选取下一个便利的数作为新的候选众数。一直到数组尾部,此时的候选众数,就是真正的众数。
原理是真正的众数足够多,可以抵消掉所有的非众数。

  • 时间复杂度:O(n)
  • 空间复杂度:O(1)
class Solution {
    public int majorityElement(int[] nums) {
        int tempMajor = nums[0];
        int x = 1;
        for(int i=1;i<nums.length;i++){
            if(x==0)   tempMajor = nums[i];
            if(nums[i]==tempMajor){
                x++;
            }else{
                x--;
            }
        }
        return tempMajor;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值