LeetCode229.求众数II

题目来源:https://leetcode-cn.com/problems/majority-element-ii/description/

题目描述:

本题是在上篇博客题目的难度上做了略微提升,上题详见:https://blog.csdn.net/qq_39241239/article/details/82871294 

算法描述:相信你已经阅读了上一篇博客,那么就好办了。本题有两种效率较高的做法。

第一种:摩尔投票法:

题目给了我们一个 nums array, 让我们找出所有 数量超过 n/3 的众数。这一题与 众数之一 的区别在于,众数之一 只要找到一个 众数大于 n/2 的就可以。这一题要找到所有的数量 大于n/3的众数,其实,最多也就会有两个 大于n/3 的众数。因为可能会出现两个众数,而且是要数量 大于n/3 的,所以我们需要遍历两次nums array。

  第一次遍历 需要找出数量出现最多的 两个数字;

  第二次遍历 需要找出准确的出现次数,因为第一次遍历可能会漏掉一些次数;

  最后,要检查次数大于 n/3 的 才算众数。

代码如下:

class Solution {
    public List<Integer> majorityElement(int[] nums) {
      		List<Integer> list = new ArrayList<Integer>();
		int result1 = 0, result2 = 0, count1 = 0, count2 = 0;
		for (int x : nums) {
			if (x == result1)
				count1++;
			else if (x == result2)
				count2++;
			else if (count1 == 0) {
				result1 = x;
				count1 = 1;
			} else if (count2 == 0) {
				result2 = x;
				count2 = 1;
			} else {
				count1--;
				count2--;
			}
		}
		count1 = count2 = 0;
		for(int x : nums) {
			if(x == result1)
				count1++;
			if(x == result2)
				count2++;
		}
		if(count1 > (nums.length/3))
			list.add(result1);
		if((count2 > (nums.length/3)) && (result2!=result1))
            list.add(result2);
		return list;  
    }
}

第二种:先排序,然后再遍历

class Solution {
    public List<Integer> majorityElement(int[] nums) {
        int n=nums.length/3,count=1;
        List<Integer> result=new ArrayList<>();
        Arrays.sort(nums);
        for(int i=0;i<nums.length-1;i++){
            if(nums[i]==nums[i+1])
                count++;
            else{
                if(count>n)
                    result.add(nums[i]);
                count=1;
            }
        }
        if(count>n && nums.length>0)
            result.add(nums[nums.length-1]);
        return result;
    }
}

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值