原题:169. 多数元素
给定一个大小为 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) 的算法解决此问题。
本题不考虑复杂度限制不难解决,难点在于进阶部分,要求时间复杂度O(n) & 空间复杂度O(1),昨天下班到现在没有想出好的解决办法,通过AI了解到可以通过摩尔投票算法解决。
摩尔投票算法的思想是,将每一个元素视为一个潜在的候选元素,开始选择第一个元素为候选元素并计票。往后每出现一个和候选元素相同的元素票数+1,不相同的元素票数-1。当第一个选定的候选元素票数为0时表明截止此时存在相同数量个不同于候选元素的其他元素,所以它们之间可以“抵消”(因为题意中的多数元素是指过半的元素),抵消之后重新选择下一个元素为候选元素。这样重复抵消之后剩下的元素一定是过半的元素。
from typing import Listclass Solution:def majorityElement(self, nums: List[int]) -> int:cnt, candidate = 0, Nonefor num in nums:if cnt == 0:candidate = numcnt += (1 if num == candidate else -1)return candidateif __name__ == '__main__':s = Solution()print(s.majorityElement([3, 2, 3])) # 3print(s.majorityElement([2, 2, 1, 1, 1, 2, 2])) # 2
算法仅当输入中存在绝对过半(⌊n/2⌋+1)的元素才会保证返回正确值。
⌊x⌋:向下取整。
该问题还可以进一步变种求出现次数大于 k n \frac{k}{n} nk的元素,n为输入元素长度。
https://kimi.moonshot.cn/share/ctuan8mf5kufi6mnh4mg