利用摩尔投票算法解决LeetCode 169与229题

- 日理万妓 2022-03-10 01:58 294阅读 0赞

摩尔投票算法是今天在LeetCode 169(Majority Element)题看到的算法.本篇文章将从本题出发探讨摩尔投票算法,并且利用本算法进而扩展解决LeetCode 229(Majority Element2)题.(本文使用Java编写代码)

一、LeetCode 169(Majority Element)原题介绍:

给定一个大小为n的数组,找到其中出现次数超过元素总个数一半的数(出现次数>n/2).我们可以假设数组是非空的,并且给定的数组总是存在出现次数超过元素总个数一半的数.

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

例题分析: [2,2,1,1,1,2,2]这个数组元素总个数为7,一半为3.5,也就是说这个数组中需要有某个数的出现次数要大于3.5次,也就是至少是4次.其中2出现了4次,所以符合条件输出,而1出现了3次,不符合条件.

以下是常用的一些方法:

1.遍历数组存入HashMap并计数,最后遍历HashMap输出符合条件的数

  1. Map<Integer, Integer> map=new HashMap<Integer, Integer>();
  2. int[] nums={2,3,1,4,1,5,5,5,5,5,5};
  3. for(int i=0;i<nums.length;i++){
  4. if((map.get(nums[i]))==null){
  5. map.put(nums[i], 1);
  6. }else{
  7. int num=map.get(nums[i]);
  8. map.put(nums[i], num+1);
  9. }
  10. }
  11. Iterator<Integer> it=map.keySet().iterator();
  12. while(it.hasNext()){
  13. int num=it.next();
  14. if(map.get(num)>nums.length/2) {
  15. System.out.println("大多数为:"+num);
  16. }
  17. }

2.排序法:对数组排序后,其中出现次数大于一半的肯定在中间

  1. int[] nums= {2,3,1,4,1,5,5,5,5,5,5};
  2. Arrays.sort(nums);
  3. System.out.println(nums[nums.length/2]);

二、LeetCode 169(Majority Element)的摩尔投票算法版:

  1. int[] nums=new int[]{2,3,1,4,1,5,5,5,5,5,5};
  2. int maj=nums[0];
  3. int count=0;
  4. for(int i=0;i<nums.length;i++) {
  5. if(count==0) {
  6. maj=nums[i];
  7. count=1;
  8. }else if(maj==nums[i]) {
  9. count++;
  10. }else{
  11. count--;
  12. }
  13. }
  14. System.out.println(maj);

三、LeetCode 229(Majority Element2)的摩尔投票算法版:

  1. int[] nums=new int[]{1,1,1,4,1,5,5,5,5,5,5};
  2. int maj1=nums[0];
  3. int maj2=nums[1];
  4. int count1=0;
  5. int count2=0;
  6. for(int i=0;i<nums.length;i++) { //算法核心,找出大多数的候选值
  7. if(maj1==nums[i]) {
  8. count1++;
  9. }else if(maj2==nums[i]) {
  10. count2++;
  11. }else if(count1==0) {
  12. maj1=nums[i];
  13. count1=1;
  14. }else if(count2==0) {
  15. maj2=nums[i];
  16. count2=1;
  17. }else {
  18. count1--;
  19. count2--;
  20. }
  21. }
  22. count1=0;
  23. count2=0;
  24. for(int i=0;i<nums.length;i++) { //统计确定候选值是真的大多数
  25. if(nums[i]==maj1) {
  26. count1++;
  27. }else if(nums[i]==maj2) { //使用else if避免当数组为[0,0,0]时,出现两个0为结果的情况
  28. count2++;
  29. }
  30. }
  31. if(count1>nums.length/3) {
  32. System.out.println(maj1);
  33. }
  34. if(count2>nums.length/3) {
  35. System.out.println(maj2);
  36. }

最后感谢yealxxy等人的博客让我更深入的理解了摩尔投票算法,附上博客传送门

发表评论

表情:
评论列表 (有 0 条评论,294人围观)

还没有评论,来说两句吧...

相关阅读

    相关 投票

    背景: leetcode 169题求一个数组中,出现次数大于 n/2;的元素 如果在一个遍历中解决这个问题?? 答案就是摩尔投票法。 摩尔投票法:用一个计数器,每次当计

    相关 投票

    提问: 给定一个int型数组,找出该数组中出现次数大于数组长度一半的int值。 解决方案: 遍历该数组,统计每个int值出现次数,再遍历该数组,找出出现次数大于数组长度一半的

    相关 投票

    摩尔投票 问题背景 在一个大厅中,每位票民手中都有一张票他可以给自己喜欢的候选人偷一票,我们现在已知每个票民的投票结果。 问:如何通过一次遍历找到票数超过一半的