算法:摩尔投票法

问题描述:

遇到一个算法的题目,找到数组中出现次数最多的数,并且判断是否超过了数组一半。

解决方案

我最开始想了3种方案,
第一种:用hashSet把数据传入,并且记录false的次数,最后和数组长度比较。
第二种:用两个指针循环比较数据有没有重复的,有的话count+1,最和数组长度比较。
第三种:第三种就是本文要介绍的一种算法,摩尔投票法。前面两种都能实现功能,但有个问题,在复杂度和空间都很高。

摩尔投票法

public static void main(String[] args) {
    
    
        /**
         * 如果数组中多一半的数都是同一个,则称之为主要元素。给定一个整数数组,找到它的主要元素。若没有,返回-1。
         *
         * 示例 1:
         * 输入:[1,2,5,9,5,9,5,5,5]
         * 输出:5
         *  
         * 示例 2:
         * 输入:[3,2]
         * 输出:-1
         *
         * 示例 3:
         * 输入:[2,2,1,1,1,2,2]
         * 输出:2
         *
         */

        int[] nums = {
    
    1,2,5,9,5,9,5,5,5};

        int i = 0;
        int count1 = 0;
        //遍历整个数组,在遍历的过程中找到出现次数最多的数
        for (int num : nums) {
    
    
            if (count1 == 0) {
    
    
                i = num;
                count1++;
            } else {
    
    
                if (i == num) {
    
    
                    count1++;
                } else {
    
    
                    count1--;
                }
            }
        }
        int count2 = 0;
        //先判断是否有众数
        if (count1 <= 0) {
    
    
            System.out.println(i);
        } else {
    
    
            //确认有众数之后就遍历数组  确定众数出现的次数
            for (int num : nums) {
    
    
                if (num == i) {
    
    
                    count2 ++;
                }
            }
        }
        //判断出现的次数是否超过数组的一半
        if (count2 > nums.length / 2) {
    
    
            System.out.println(i);
        }
    }

总结

这个算法不止可以找到出现次数超过数组长度一半,也可以找到三分之一的等等,都可以找到。

猜你喜欢

转载自blog.csdn.net/weixin_46687295/article/details/106172051