其他分享
首页 > 其他分享> > LeetCode每日一题 229. 求众数 II

LeetCode每日一题 229. 求众数 II

作者:互联网

229. 求众数 II

Tag: Array

Difficulty: Medium

Link: https://leetcode-cn.com/problems/majority-element-ii/

分析

要求一个数组中所有超过[n/3](向下取整)的元素,比较容易想到的是用map方法,统计每个不同元素的数量,但是本题要求用O(1)的空间复杂度。所以这里需要一个新的方式——摩尔投票法

摩尔投票法解决的问题是,在任意多的候选人中,选出票数超过一半的的那个人。

它表明这样的规律:在任何数组中,出现次数大于该数组长度一半的值只能有1

假如有这样的数组表示投票 [A, B, C, A, A]

第一次遍历:抵消阶段

选择第一张票作为候选人,[A, 1]

第二张票与第一张票抵消, [A, 0]

第三张票与第一张票不同,并且计数为0,替换,[C, 1]

第四张票抵消 [C, 0]

第五张票替换 [A, 1]

最后获取A为可能的候选人

第二次遍历:计数阶段

注意如果投票是[A, B, C], 那么最后统计到[C, 1]也不能说明C的票超过半数,所以还要再遍历一次

遍历得到A的数量为3,超过半数,符合条件

那么,对于1/3:在任何数组中,出现次数大于该数组长度1/3的值最多只有2

对于1/3,则需要选择两个可能的候选人

推广到1/(m+1): 在任何数组中,出现次数大于该数组长度1/(m+1)的值最多只有m

题解

class Solution {
    public List<Integer> majorityElement(int[] nums) {
        // 创建返回值
        List<Integer> res = new ArrayList<>();
        if (nums == null || nums.length == 0) return res;
        // 初始化两个候选人candidate,和他们的计票
        int cand1 = nums[0], count1 = 0;
        int cand2 = nums[0], count2 = 0;

        // 摩尔投票法,分为两个阶段:配对阶段和计数阶段
        // 配对阶段
        for (int num : nums) {
            // 投票
            if (cand1 == num) {
                count1++;
                continue;
            }
            if (cand2 == num) {
                count2++;
                continue;
            }

            // 第1个候选人配对
            if (count1 == 0) {
                cand1 = num;
                count1++;
                continue;
            }
            // 第2个候选人配对
            if (count2 == 0) {
                cand2 = num;
                count2++;
                continue;
            }

            count1--;
            count2--;
        }

        // 计数阶段
        // 找到了两个候选人之后,需要确定票数是否满足大于 N/3
        count1 = 0;
        count2 = 0;
        for (int num : nums) {
            if (cand1 == num) count1++;
            else if (cand2 == num) count2++;
        }

        if (count1 > nums.length / 3) res.add(cand1);
        if (count2 > nums.length / 3) res.add(cand2);

        return res;
    }
}

标签:数组,nums,++,II,num,229,count1,count2,LeetCode
来源: https://blog.csdn.net/Galahadzhou/article/details/104640569