leetcode169多数元素
题目描述
给定一个大小为 n
的数组 nums
,找出其中出现次数超过 ⌊ n/2 ⌋
的元素。
你可以假设数组总是存在多数元素。
示例
示例 1:
输入: nums = [3,2,3] |
示例 2:
输入: nums = [2,2,1,1,1,2,2] |
进阶要求
- 你能在时间复杂度 O(n)、空间复杂度 O(1) 的条件下完成算法吗?
解法 1:哈希表(map 计数)
思路
我们可以使用哈希表(unordered_map
)统计每个元素出现的次数,然后找到出现次数超过 ⌊ n/2 ⌋
的元素。
代码
|
复杂度分析
- 时间复杂度:O(n),遍历数组一次统计出现次数。
- 空间复杂度:O(n),哈希表存储了最多
n
个不同的数。
解法 2:排序
思路
- 由于多数元素的出现次数超过
⌊ n/2 ⌋
,如果我们对数组进行排序,中间的元素(索引n/2
处)一定是多数元素。 - 直接返回
nums[n/2]
。
代码
|
复杂度分析
- 时间复杂度:O(n log n)(排序的开销)。
- 空间复杂度:O(1)(原地排序)。
解法 3:摩尔投票法
思路
- 由于多数元素出现的次数超过
⌊ n/2 ⌋
,如果我们用一个count
计数器,每次遇到相同的元素就加一,不同的元素就减一:count == 0
时,我们假设当前元素是多数元素,并将count
设为 1。- 继续遍历,最后剩下的
candidate
就是多数元素。
代码
|
复杂度分析
- 时间复杂度:O(n),遍历数组一次即可确定多数元素。
- 空间复杂度:O(1),只使用了额外的变量
candidate
和count
。
摩尔投票法的直觉
- 假设
x
是多数元素,y
是非多数元素。 - 多数元素的数量 > 其他所有元素的总和,所以最终
x
一定会占据主导地位。
数学证明
假设多数元素是M
,它出现了 k > n/2
次
假设整个数组长度为 n
,其他所有元素的数量是 n - k < k
。
最坏情况下,
M
与其他元素交错排列M, X, M, X, M, X, M, X, M, ...
由于
M
的数量比X
多,在投票过程中M
仍然会剩余。假设
X
们全部抵消M
,但M
仍然有k - (n - k) = 2k - n
个存活,而X
被完全抵消。因为
k > n/2
,所以2k - n > 0
,即M
仍然剩下,最终成为candidate
。
无论
M
如何分布,它都不会被完全抵消设
M
的出现次数为x
,所有其他元素的出现次数总和为y
。由于
x > y
,在遍历的过程中,M
可能会被y
抵消掉y
次,但M
仍然剩余x - y
次。因此,最终
M
仍然是最多的,且一定会成为candidate
。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 森林!