侧边栏壁纸
博主头像
GabrielxD

列車は必ず次の駅へ。では舞台は?私たちは?

  • 累计撰写 471 篇文章
  • 累计创建 108 个标签
  • 累计收到 9 条评论

目 录CONTENT

文章目录

【哈希表, 排序, 分治, 多数投票算法】多数元素

GabrielxD
2022-04-12 / 0 评论 / 0 点赞 / 42 阅读 / 446 字 / 正在检测是否收录...
## 题目

169. 多数元素

剑指 Offer 39. 数组中出现次数超过一半的数字


给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数 大于 n/2 的元素。

你可以假设数组是非空的,并且给定的数组总是存在多数元素。

示例 1:

输入:[3,2,3]
输出:3

示例 2:

输入:[2,2,1,1,1,2,2]
输出:2

进阶:

  • 尝试设计时间复杂度为 O(n)、空间复杂度为 O(1) 的算法解决此问题。

解题

方法一:哈希表

思路

使用哈希表统计每个数字出现的次数,找出出现次数大于 数组长度/2 的元素并返回。

代码

class Solution {
    public int majorityElement(int[] nums) {
        int halfLen = nums.length >> 1;
        Map<Integer, Integer> frequency = new HashMap<>();
        for (int num : nums) {
            int currFreq = frequency.getOrDefault(num, 0) + 1;
            if (currFreq > halfLen) {
                return num; // 找到直接返回
            }
            frequency.put(num, currFreq);
        }

        return -1; // 防止报错 "Missing return statement"
    }
}

方法二:排序

思路

要找的是出现次数大于 数组长度/2 的元素,那么数组排序后无论数组结构怎样该元素都必在数组中间有至少一个。

image-20220412170749415

代码

class Solution {
    public int majorityElement(int[] nums) {
        Arrays.sort(nums);
        return nums[nums.length >> 1];
    }
}

方法三:摩尔投票算法

思路

image-20220412172228713

代码

class Solution {
    public int majorityElement(int[] nums) {
        int candidate = nums[0]; // 候选
        int count = 1; // 候选权重
        for (int i = 1; i < nums.length; i++) {
            if (count == 0) {
                // 候选权重为零后替换当前候选并重置权重
                candidate = nums[i];
                count = 1;
                continue;
            }

            if (candidate == nums[i]) {
                // 若与候选相同,权重增减,反之
                count++;
            } else {
                count--;
            }
        }

        return candidate; // 返回权重
    }
}
0

评论区