229. 求众数 II
Difficulty: 中等
给定一个大小为n的数组,找出其中所有出现超过 ⌊ n/3 ⌋
次的元素。
说明: 要求算法的时间复杂度为 O(n),空间复杂度为 O(1)。
示例 1:
输入: [3,2,3]
输出: [3]
示例 2:
输入: [1,1,1,3,3,2,2,2]
输出: [1,2]
Solution
好想吐槽,为啥有Ⅱ没有Ⅰ。。原来有道题是找半数元素的:169. 多数元素
因为对复杂度有限制,无脑办法们按理说不能用。所以用摩尔投票法。
摩尔投票法分两步,抵消&检验。
- 抵消。如果要找出现超过一半的元素,就在列表里找俩不一样的元素两两抵消,最多剩下一个。设一个候选列表(因为这种情况最多一个候选者,所以列表里就一个位置),哪位有票数就让给它位置。但是剩下的这个不一定满足条件,比如
[3,3,3,2,2,2,2,1,1]
抵消完剩下了不合条件的1。 - 检验。把列表再遍历一遍,为这个可能的候选者计数,判断是否符合条件。
1/2时的例子⬇
nums=[3,3,3,2,2,2,2,1,1]
win=[nums[0],1]
for x in nums[1:]:
if x==win[0]:
win[1]+=1
else:
if win[1]>0:
win[1]-=1
else:
win=[x,1]
if win[1]>0:
s=0
for x in nums:
if x==win[1]:
s+=1
if s/len(nums)>0.5:
print(win[0])
else:print('没有')#...
else:print('没有')
这题要三分之一,就三三抵消,原理不变。
问题:力扣还分python跟python3啊…我说咋我的1/3还有Ca/len(nums)算出来都是0…
((众所周知,python是世界上最好的两种语言
class Solution:
def majorityElement(self, nums: List[int]) -> List[int]:
a,b,Ca,Cb=0,0,0,0
#ab没必要从nums里找好,反正票数为0,遇到个数就给它压下去了
for x in nums:
if x==a:
Ca+=1
elif x==b:
Cb+=1
elif Ca>0 and Cb>0:#抵消
Ca-=1
Cb-=1
elif Ca==0:#换人(不要用if,要不会把抵消完的x也计进来
a=x
Ca=1
elif Cb==0:
b=x
Cb=1
re=[]
l=len(nums)
if Ca>0:
Ca=0
for x in nums:
if x==a:
Ca+=1
if Ca/len(nums)>1/3:
re+=[a]
if Cb>0:
Cb=0
for x in nums:
if x==b:
Cb+=1
if Cb/len(nums)>1/3:
re+=[b]
return re
这还差不多。。