摩尔投票法的应用

文章目录

多数元素

在这里插入图片描述

  • 关于摩尔投票法:

候选人(cand_num)初始化为nums[0],票数count初始化为1
当遇到与cand_num相同的数,则票数count = count + 1,否则票数count = count - 1
当票数count0时,更换候选人,并将票数count重置为1
遍历完数组后,cand_num即为最终答案。

  • 为何这行得通呢?

投票法是遇到相同的则票数 + 1,遇到不同的则票数 - 1。
且“多数元素”的个数> ⌊ n/2 ⌋,其余元素的个数总和<= ⌊ n/2 ⌋。
因此“多数元素”的个数 - 其余元素的个数总和 的结果 肯定 >= 1。
这就相当于每个“多数元素”和其他元素 两两相互抵消,抵消到最后肯定还剩余至少1个“多数元素”。

所以无论数组是1 2 1 2 1,亦或是1 2 2 1 1,总能得到正确的候选人。

public class Main {
    public int majorityElement(int[] nums) {
        int cand_num = nums[0];
        int count = 1;
        for (int i = 1; i < nums.length; i++) {
            if (cand_num == nums[i]) {
                count++;
            } else {
                if (--count == 0) {
                    cand_num = nums[i];
                    count = 1;
                }
            }
        }
        return cand_num;
    }
}

求众数II

在这里插入图片描述
大于1/3意味着最多可能有两个候选人,所以我们就假设为两个候选人进行投票
初始化从第0个人开始,没人0票
如果遇到候选人,票数+1
如果没有遇到候选人且候选人票数为0,更换候选人
如果没有遇到候选人且候选人票数不为0,所有候选人票数-1
然后再统计两个候选人的票数
如果大于1/3就当选
题解参考
关于摩尔投票的动画可以去题解看

public class Main {
    public List<Integer> majorityElement(int[] nums) {
        List<Integer> res = new ArrayList<>();
        if (nums == null || nums.length == 0) return res;
        //定义两个候选人的票数
        int cand1 = 0, cand2 = 0;
        int count1 = 0, count2 = 0;
        //开始投票
        for (int num : nums) {
            //如果是候选人1
            if (num == cand1) {
                count1++;
                continue;
            }
            //如果是候选人1
            if (num == cand2) {
                count2++;
                continue;
            }
            //如果不是cand1也不是cand2,判断有没有候选人还没有票,没有就换人
            if (count1 == 0) {
                cand1 = num;
                count1++;
                continue;
            }
            if (count2 == 0) {
                cand2 = num;
                count2++;
                continue;
            }
            //如果两个候选人都还有票,就都-1
            count1--;
            count2--;
        }
        //验证票数是否满足大于1/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;
    }
}
发布了48 篇原创文章 · 获赞 95 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/qq_41170102/article/details/105029569