leetcode.169 多数元素

 方式一:哈希表

哈希表中存储的键值是唯一的,用key存储数组元素,value用来存储元素出现的个数

class Solution {
    public int majorityElement(int[] nums) {
        if(nums==null || nums.length==0)
            return 0;
        HashMap<Integer,Integer> map = new HashMap();
        for(int i=0;i<nums.length;i++)
        {
            if(!map.containsKey(nums[i]))
            map.put(nums[i],1);
            else
            map.put(nums[i],map.get(nums[i])+1);
        }
        for(int num:map.keySet())
        {
            if(map.get(num)>nums.length/2)//某个元素出现的次数大于长度的一半,该数即为多数
            return num;
        }
        return 0;
    }
}

时间复杂度O(n)  

空间复杂度O(n)

方式二:先排序,取中间元素【多数占半数以上】

class Solution {
    public int majorityElement(int[] nums) {
        Arrays.sort(nums);
        return nums[nums.length/2];
    }
}

时间复杂度 o(nlogn)【排序消耗】

空间复杂度 o(1)

方法三:分治(递归)

1、每次对半分,去找左右两边的多数元素,然后在左右合并的区间中确定当前区间的多数元素是左边还是右边的,把无数个小区间的多数元素找出来,然后进行区间合并,最后找出大区间的多数元素 

2、分到只剩一个元素(终止条件)此时多数元素是它自己

为什么可以用递归?

大问题拆解成子问题

存在终止条件

大问题和小问题的求解方式相同

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];//这里返回right也行
        int mid=left+(right-left)/2;
        int leftMajority=getMajority(nums,left,mid);
        int rightMajority=getMajority(nums,mid+1,right);
        if(leftMajority==rightMajority)//左右多素元素相同,返回其中之一这里选左多数
        return leftMajority;
//不同,则计算此区间内左右两个子区间“多数元素”分别出现的次数,返回其大
        int leftCount=0;
        int rightCount=0;
        for(int i=left;i<=right;i++)
        {
            if(nums[i]==leftMajority)
            leftCount++;
            else if(nums[i]==rightMajority)
            rightCount++;
        }
//左边多数元素出现次数大于右边,返回左多数元素,否则返回右边,这里是左右区间合并成大区间的比较
        return leftCount>rightCount?leftMajority:rightMajority;
    }
}

空间复杂度是logn,单边递归栈的压入

时间复杂度nlogn  主定理?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qq_40396568

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值