本文首发于我的博客:https://belindayang.cn/
题目:
leetcode169
给定一个长度为n的数组,求其中出现次数超过n/2次的元素,题目规定该元素必定存在。
算法思路
方法一:
以数组元素为key,出现次数为value,遍历数组,将每个元素出现的次数记录在字典中,然后求字典中统计次数最大的key值。
时间复杂度为o(n),用到了字典,所以空间复杂度也是o(n)
代码如下:
class Solution(object):
def majorityElement(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
if nums and len(nums)==0:
return 0
d={}
for num in nums:
d[num]=d.get(num,0)+1
max,maxcnt=0,0
for num,cnt in d.items():
if cnt>maxcnt:
maxcnt=cnt
max=num
return max
方法二:
将数组排序,由于所求元素出现的次数必定超过n/2次,所以排序后的数组第n/2个元素则为所求。
使用快排的时间复杂度为o(nlogn),所以用这种方法的时间复杂度为o(nlogn)
class Solution(object):
def majorityElement(self, nums):
n=sorted(nums)
return n[len(n)/2]
方法三:
摩尔投票法:
如果一对元素的值相同则票数加1,每次移除一对不同元素,剩下的票数最多的则为所求,因为票数超过半数,所以最后势必存在一个值为所求
时间复杂度为o(n)
class Solution(object):
def majorityElement(self, nums):
target, cnt = 0, 0
for num in nums:
if num == target:
cnt += 1
elif cnt == 0:
target, cnt = num, 1
else:
cnt-=1
return target
感觉这种摩尔投票法使用场景不是很多,也可能是笔者经验还不够所以见的比较少。
其他方法:
其实还可以用分治的方法,待补充
体会
从算法上看,方法三和方法一的时间效率会高一些,但是在leetcode上的提交结果并不算好,感觉实际的算法效率还是跟测试用例有关系
欢迎关注公众号:pipi的奇思妙想