题目:
给定一个大小为 n 的数组,找到其中的众数。众数是指在数组中出现次数大于 ⌊ n/2 ⌋
的元素。
分析:
- 最简单的方法是使用库函数对数组排序,第
⌊ n/2 ⌋
个数即为众数,但时间复杂度为O(nlgn) - 为降低时间复杂度,采用计数方式,并记录最大频次和对应元素,遍历后返回最大频次对应元素,时间复杂度O(n),空间复杂度O(n)
代码:
class Solution(object):
def majorityElement(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
numDict = {}
maxCounts = [0,0]
for x in nums:
v = numDict.get(x) + 1 if numDict.get(x) else 1
numDict[x] = v
if v > maxCounts[0]:
maxCounts = [v,x]
return maxCounts[1]
思考:
- 看讨论区找到一种时间复杂度相同,空间复杂度更有,只有O(1)的算法。思路是:选取一个主元,计数器设置为1,遍历数组,当前元素与主元相同,计数器加1,否则减1;当计数器减为0,将当前元素设为主元,重复上述步骤,由于众数数量大于数组长度一半,因此最终保留的主元一定是总数,代码如下:(leetcode caikehe)
def majorityElement(self, nums): count, cand = 0, 0 for num in nums: if num == cand: count += 1 elif count == 0: cand, count = num, 1 else: count -= 1 return cand
- 以上代码可以增加对count的判断,若count大于剩余元素数量,则跳出遍历,直接返回主元,对于众数分布整体靠前的情况下,可以节约时间
- 以上代码在众数不存在情况下无法得出正确结果
- 我自己的代码,只需增加对最大频次与数组长度一半长度比对,可以适应无众数的情形