leetcode
leetcode 151 ~ 200
多数元素

多数元素

难度:

标签:

题目描述

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

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

 

示例 1:

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

示例 2:

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

 

提示:
  • n == nums.length
  • 1 <= n <= 5 * 104
  • -109 <= nums[i] <= 109

 

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

代码结果

运行时间: 20 ms, 内存: 17.7 MB


/*
思路:使用 Java Stream,我们可以通过分组并统计每个元素出现的次数,然后找到出现次数最多的元素。
1. 将数组转换为流。
2. 使用 Collectors.groupingBy() 方法按元素分组,并统计每个元素出现的次数。
3. 找到出现次数最多的元素。
*/
import java.util.*;
import java.util.stream.Collectors;
 
public class Solution {
    public int majorityElement(int[] nums) {
        return Arrays.stream(nums)
                .boxed()
                .collect(Collectors.groupingBy(e -> e, Collectors.counting()))
                .entrySet()
                .stream()
                .max(Map.Entry.comparingByValue())
                .get()
                .getKey();
    }
}

解释

方法:

这个题解采用了摩尔投票算法。该算法的基本思想是用一种有效的方式找出列表中的多数元素。算法维护一个候选多数元素和一个计数器,遍历数组中的每个元素,当计数器为0时,将当前元素作为候选多数元素,并初始化计数器为1。如果遇到的元素等于当前候选元素,则计数器加1,否则计数器减1。由于多数元素的数量大于n/2,所以最后候选元素一定是多数元素。

时间复杂度:

O(n)

空间复杂度:

O(1)

代码细节讲解

🦆
摩尔投票算法是如何确保最终候选元素确实是多数元素,尤其是在遇到计数器为零时频繁更换候选者的情况下?
摩尔投票算法之所以能确保最终候选元素是多数元素,是基于一个关键假设:数组中存在一个元素的数量超过了数组长度的一半。因此,即使在遇到计数器为零时频繁更换候选者的情况下,真正的多数元素由于数量优势,最终会使得计数器的值在算法结束时为正。每次计数器归零时更换候选者,其实是一次重新计数的开始,而真正的多数元素总能在遍历结束时保持计数器为正数,从而成为最终的候选者。
🦆
在摩尔投票算法中,如果数组中的多数元素分布非常不均匀,这种情况会对算法的效率有何影响?
摩尔投票算法的效率主要依赖于遍历数组的次数,其时间复杂度始终是O(n),即与数组长度成线性关系。多数元素的分布是否均匀并不影响算法的时间复杂度。无论多数元素如何分布,算法都只需要一次遍历即可确定候选者。分布的不均匀可能会导致计数器的变化更加频繁,但这并不影响算法总体的遍历次数和时间复杂度。
🦆
算法实现中提到的计数器增减操作,这种方法是否能处理所有的输入情况,例如所有元素均不相同的数组?
摩尔投票算法的前提是存在一个多数元素,即某个元素出现的次数超过数组长度的一半。如果一个数组中所有元素均不相同,则没有任何一个元素的出现次数能超过数组长度的一半。在这种特殊情况下,摩尔投票算法不适用,因为它依赖于多数元素的存在。如果用此算法处理所有元素均不相同的数组,算法会返回一个结果,但这个结果不具有实际意义,因为并不存在一个真正的多数元素。

相关问题

多数元素 II

给定一个大小为 的整数数组,找出其中所有出现超过 ⌊ 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

 

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

检查一个数是否在数组中占绝大多数

检查一个数是否在数组中占绝大多数