LeetCode——229. 求众数 II(Java)

题目描述

题干:
给定一个大小为 n 的整数数组,找出其中所有出现超过 ⌊ n/3 ⌋ 次的元素。

示例 1:
输入:[3,2,3]
输出:[3]

示例 2:
输入:nums = [1]
输出:[1]

示例 3:
输入:[1,1,1,3,3,2,2,2]
输出:[1,2]

题解思路

返回所有满足条件的众数,首先想到的就是遍历得到每个元素的个数然后统计

用哈希表存储每个元素出现的次数,然后统计出现个数大于 n/3 的元素返回

这里说一说这里用到的第二种方法,叫摩尔投票法,也叫多数投票法

传统的方式就是两个人进行选举采取的常用方式,核心思想是抵消和计数

因为我们都默认统计第一个元素为标准,从1开始,每次遇到相同元素则加一

遇到不同的元素相当于抵消掉自己一票,而当自己为个数为0的时候也就丧失了竞争力

这个时候就切换到下一个竞选者,这里是两个人竞争的结果,因为题目是大于 n/3

所以我们要对此方法进行升级一下,一次统计两个元素的票数,其他不变

正确代码

    // 哈希表
    public List<Integer> majorityElement(int[] nums) {
        HashMap<Integer, Integer> hashMap = new HashMap<>();

        // 遍历数组获取每个数字出现的次数
        for (int num : nums) {
            if (hashMap.containsKey(num)) {
                hashMap.put(num, hashMap.get(num) + 1);
            } else {
                hashMap.put(num, 1);
            }
        }

        // 找到众数
        List<Integer> ansList = new ArrayList<>();
        for (Integer integer : hashMap.keySet()) {
            if (hashMap.get(integer) > (nums.length / 3)) {
                ansList.add(integer);
            }
        }
        return ansList;
    }

    // 摩尔投票法(plus版本)
    public List<Integer> majorityElement01(int[] nums) {
        int element1 = 0;
        int element2 = 0;
        int vote1 = 0;
        int vote2 = 0;

        for (int num : nums) {
            if (vote1 > 0 && num == element1) {
                vote1++;
            } else if (vote2 > 0 && num == element2) {
                vote2++;
            } else if (vote1 == 0) {
                element1 = num;
                vote1++;
            } else if(vote2 == 0) {
                element2 = num;
                vote2++;
            } else {
                vote1--;
                vote2--;
            }
        }

        int cnt1 = 0;
        int cnt2 = 0;
        for (int num : nums) {
            if (vote1 > 0 && num == element1) {
                cnt1++;
            }
            if (vote2 > 0 && num == element2) {
                cnt2++;
            }
        }

        List<Integer> ansList = new ArrayList<>();
        if (vote1 > 0 && cnt1 > (nums.length /3)) {
            ansList.add(element1);
        }
        if (vote2 > 0 && cnt2 > (nums.length /3)) {
            ansList.add(element2);
        }

        return ansList;
    }

总结

这里其实如果使用哈希表方法就是简单问题,不过摩尔计数法的思路确实可以用到很多方面

这个思路核心的思路就是对拼消耗,针对不同的标准来达成满足条件的元素

如果文章存在问题或者有更好的题解,欢迎在评论区斧正和评论,各自努力,你我最高处见
posted @ 2021-10-22 11:10  21岁还不是架构师  阅读(74)  评论(0编辑  收藏  举报