• 【LeetCode】多数元素 II [M](摩尔投票)


    229. 多数元素 II - 力扣(LeetCode)

    一、题目

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

    示例 1:

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

    示例 2:​​​​​​​

    输入:nums = [1]
    输出:[1]

    示例 3:​​​​​​​

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

    提示:

    • 1 <= nums.length <= 5 * 104
    • -109 <= nums[i] <= 109

    二、代码

    1. class Solution {
    2. public List majorityElement(int[] nums) {
    3. HashMap cntMap = new HashMap<>();
    4. int n = nums.length;
    5. List ans = new ArrayList();
    6. int k = 3;
    7. for (int i = 0; i < n; i++) {
    8. // 候选表中存在nums[i]
    9. if (cntMap.containsKey(nums[i])) {
    10. // 直接将该值的血量++
    11. int value = cntMap.get(nums[i]);
    12. cntMap.put(nums[i], value + 1);
    13. // 候选表中不存在nums[i]
    14. } else {
    15. // 当前Map表还没有满,就将nums[i]加入到Map候选表中,作为候选值
    16. if (cntMap.size() < k - 1) {
    17. cntMap.put(nums[i], 1);
    18. // 当前Map表已经满了,就将表中所有候选值的血量减1,然后如果剪到0的从Map中移除
    19. } else {
    20. // 使用迭代器边遍历,边移除才不会报错
    21. Iterator> iterator = cntMap.entrySet().iterator();
    22. while (iterator.hasNext()) {
    23. Map.Entry entry = iterator.next();
    24. int key = entry.getKey();
    25. int value = entry.getValue();
    26. if (--value == 0) {
    27. iterator.remove();
    28. } else {
    29. cntMap.put(key, value);
    30. }
    31. }
    32. }
    33. }
    34. }
    35. // 如果没有候选值,就说明这个表里面没有次品为n/k的数
    36. if (cntMap.size() == 0) {
    37. return ans;
    38. }
    39. // 找到候选值,去遍历数组来确定他们的真实词频,然后判断是否超过了n/k次,超过了就加入到ans
    40. for (Map.Entry entry : cntMap.entrySet()) {
    41. int key = entry.getKey();
    42. int cnt = 0;
    43. for (int i = 0; i < n; i++) {
    44. if (nums[i] == key) {
    45. cnt++;
    46. }
    47. }
    48. if (cnt > n / k) {
    49. ans.add(key);
    50. }
    51. }
    52. return ans;
    53. }
    54. }

    三、解题思路 

    上面的代码写的是通用解,可以找到数组中所有词频大于n/k的值。

    通过遍历数组,维护候选值和对应的血量,只要最后又剩下的候选值,就说明有可能存在词频大于n/k的数,然后在数组中遍历一下候选值,统计他们的真实词频,看是否大于n/k,是的话就加入到ans中。

    维护规则:

    • 遍历数组时碰到了候选值,就将这个候选值对应的血量++。
    • 如果此时有表还没有满,并且遍历到的数不是候选值,就将这个数加入到表中作为一个候选值。
    • 如果此时候选值表已经满了,遍历到的数又不是候选值,那么就将表中所有的候选值血量--,如果出现血量为0的,就将这个候选值从表中删除。
  • 相关阅读:
    Shell编程概述
    【系统分析师之路】第十五章 复盘数据库系统(数据库案例分析)
    IDEA 常用技巧
    JavaScript基础 JavaScript第一天 3. 数据类型
    Antd Procomponent 之 proForm - 高级表单
    超详细的前后端实战项目(Spring系列加上vue3)前端篇+后端篇(三)(一步步实现+源码)
    反转字符串中的元音字母
    laravel 模型Filter类型判断筛选
    铁路设备屡遭破坏!RFID电子锁实现铁路防护网破坏实时报警管理
    js实现页面元素的拖拽
  • 原文地址:https://blog.csdn.net/cy973071263/article/details/128155842