多数元素

94 阅读2分钟

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

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

示例 1:

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

示例 2:

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

进阶:

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

解法分析: 1、使用map记录<元素,出现次数>,如果次数超过n/2 即为要查找的多数元素 代码如下:

 public static int majorityElement(int[] nums) {
        Map<Integer,Integer> map = new HashMap<>();
        //统计多数元素 满足结果
        int halfLen = nums.length/2;
        for (int i = 0; i < nums.length; i++) {
            int num = nums[i];
            //元素次数  初始化是1
            int count = 1;
            if(map.containsKey(num)){
                count = map.get(num);
                count++;
            }
            //判断是否是多元素
            if(count>halfLen){
                return  num;
            }
            System.out.println(num+"元素,存储次数为 " + count);
            map.put(num,count);
            
        }
        return -1;

    }

2、排序后取中间元素,即为多数元素(多数元素个数超过数组的一半以上)

[3,2,3]
[2,3,3]

[2,2,1,1,1,2,2]
[1,1,1,2,2,2,2]

3、投票算法 将元素当做候选人,如果新元素和候选人相同,次数+1,不同次数-1(代表抵消),如果次数=0,候选人更新

[2,2,1,1,1,2,2]
元素  次数   候选人
2     1       2
2     2       2
1     1       2
1     0      
1     1       1
2     0     
2     1       2

本质上 多数元素的出现次数一定大于其他所有元素出现的次数的 总和 所以候选人的次数经过抵消后最终剩余的一定是多数元素 代码如下:

public static int majorityElement2(int[] nums) {
        //候选人
        int candiddate = -1;
        //出现次数
        int count = 0;
        for (int i = 0; i < nums.length; i++) {
            //如果出现次数为0 重置候选人
            if (count == 0) {
                candiddate = nums[i];
            }
            //根据新元素是否等于候选人 进行次数的加减操作
            if (candiddate == nums[i]) {
                count++;
            } else {
                count--;
            }
            System.out.println("元素" + nums[i] + ",词素" + count + ",候选人" + candiddate);
        }

        return candiddate;

    }