这道题用拓展的Moore投票算法,需要记录2个candidate,步骤如下:
遍历nums数组:
如果遇到等于candidate1/candidate2的数,则相应的count加1
否则:1.如果candidate1/candidate2为空,则将其设置为当前nums[i],并将count设置为1
2.否则count1/count2都减1
最后检查candidate1/candidate2是否在nums数组中出现次数>n/3次。
证明上述算法有效:
由最后一步的检查可知,输出答案一定满足在nums数组中出现次数>n/3的条件
如果一个数出现次数>n/3,则数组中不等于它的数<2n/3,只有当出现的数字不等于candidate1/candidate2时,count才会减少,这样的情况一定小于n/3次。因此该数一定会在candidate1/candidate2中出现。
class Solution(object):
def check(self, nums, candidate):
if nums.count(candidate) > len(nums)//3:
return [candidate]
else:
return []
def majorityElement(self, nums):
"""
:type nums: List[int]
:rtype: List[int]
"""
if not nums:
return []
default = min(nums) - 1
candidate1, candidate2 = default, default
count1, count2 = 0, 0
for num in nums:
# 比较是否与candidate相等
if num == candidate1:
count1 += 1
continue
elif num == candidate2:
count2 += 1
continue
# 是否需要初始化candidate
if count1 == 0:
candidate1, count1 = num, 1
elif count2 == 0:
candidate2, count2 = num, 1
else:
count1 -= 1
count2 -= 1
result = []
# 最后检查candidate出现次数是否>n/3
result.extend(self.check(nums, candidate1))
result.extend(self.check(nums, candidate2))
return result