LeetCode - 229. Majority Element II

这道题目是Moore Voting Algorithm的变体,找到数组中出现次数大于n / 3(int算法)的元素,注意到这里说的是严格的大于,所以这样的数字最多有两个。第一次遍历的时候使用Moore Sorting Algorithm找出两个可能为众数(概念不严格,借用一下)的数字,然后再进行第二次遍历进行检查它们出现的次数是不是大于n / 3,注意到题目中并没有说明一定会出现两个众数,所以在第一遍遍历之后可能出现三个情况:

1. number1和number2出现的次数均小于n / 3,那么在第二遍遍历的时候就会被排除掉;

2. number1和number2中只有一个数字出现的次数大于n / 3,那么最终只有一个留下;

3. number1和number2出现次数都大于n / 3,这就是最终的结果

时间复杂度为O(n),空间复杂度为constant,代码如下:

public class Solution {
    public List<Integer> majorityElement(int[] nums) {
        List<Integer> result = new ArrayList<Integer>();
        
        if(nums == null || nums.length == 0) return result;
        
        int number1 = nums[0];
        int number2 = nums[0];
        
        int count1 = 0;
        int count2 = 0;
        
        int length = nums.length;
        
        // Find two majority numbers 
        for(int i = 0; i < nums.length; i++){
            if(nums[i] == number1){
                count1++;
            }else if(nums[i] == number2){
                count2++;
            }else if(count1 == 0){
                number1 = nums[i];
                count1++;
            }else if(count2 == 0){
                number2 = nums[i];
                count2++;
            }else{
                count1--;
                count2--;
            }
        }
        
        // Find the frequency of two nunbers found above
        count1 = 0;
        count2 = 0;
        for(int i = 0; i < nums.length; i++){
            if(nums[i] == number1){
                count1++;
            }else if(nums[i] == number2){
                count2++;
            }
        }
        
        if(count1 > length / 3) result.add(number1);
        if(count2 > length / 3) result.add(number2);
        return result;
    }
}


这道题目的算法的思路确实比较巧妙,想了很久也难以用很通俗的语言去解释,只是自己试了很多例子之后发现都非常适用,可以记住这个在一系列数字之中寻找众数的方法,Moore Voting Algorithm一开始是为了找出数组中的众数,即出现次数大于n / 2的元素,但是可以对其进行多个变化,进而能够寻找数组中出现次数大于n / k的元素(算法的变形方式和这道题目相似)。

知识点:

1. 记住Moore Sorting Algorithm的基本算法,适用情况及其寻找数组中出现次数大于n / k的元素的变体

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值