摩尔投票
169 多数元素
知识点:摩尔投票
结论:
如果至多选一个代表,那他的票数至少要超过一半(⌊ 1/2 ⌋)的票数;
如果至多选两个代表,那他们的票数至少要超过 ⌊ 1/3 ⌋ 的票数;
如果至多选m个代表,那他们的票数至少要超过 ⌊ 1/(m+1) ⌋ 的票数。
碰到这样的问题,而且要求达到线性的时间复杂度以及常量级的空间复杂度,直接套上摩尔投票法。
class Solution:
def majorityElement(self, nums: List[int]) -> int:
'''
# 法1 哈希表
n = len(nums)
hashmap = {}
for i in nums:
hashmap[i] = hashmap.get(i, 0)+1
for key in hashmap:
if hashmap[key]>n/2:
return key
'''
# 法2 摩尔投票
n = len(nums)
count = 1
candidate = nums[0]
for i in range(1, n):
if nums[i]==candidate:
count += 1
elif count>=1: # 不等 计数减1
count -= 1
else: # count == 0
candidate = nums[i]
count += 1
return candidate
229 多数元素 II
分析:根据摩尔投票法知,最多找两个候选者
注:至多选n(n>1)个候选者时,不能判断每个人的票数是否一定大于1/(n+1),要重新计数
class Solution:
def majorityElement(self, nums: List[int]) -> List[int]:
res = []
n = len(nums)
cand1,cand2 = 0, 0
count1, count2 = 0, 0
for num in nums:
if count1>0 and num==cand1: # 是第一个元素
count1 += 1
elif count2>0 and num == cand2: # 是第2个元素
count2 += 1
elif count1 == 0: # 第一个候选者还没确定
cand1 = num
count1 += 1
elif count2 == 0:
cand2 = num
count2 += 1
else: # 不是这两个候选者
count1 -= 1
count2 -= 1
# 重新计数
rec1 = 0
rec2 = 0
for num in nums:
if count1 >0 and num == cand1: # >0是回避初始化为0
rec1 += 1
elif count2>0 and num == cand2:
rec2 += 1
if rec1>n/3:
res.append(cand1)
if rec2>n/3:
res.append(cand2)
return res