给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
输入:[3,2,3]
输出:3
来源:力扣(LeetCode)
链接:多数元素
本题的思路首先想到的是摩尔投票法,比如说多国混战,n人参战,存在一个国家有多于n/2的人参战时,这个国家必然获得最后的胜利。
那么我们模拟这个混战的过程,用夺旗来比喻。
时间复杂度为O(n),空间复杂度为O(1)
class Solution(object):
def majorityElement(self, nums):
#无人参战时,直接返回。
if not nums:
return
#有人参战时,先有一方夺旗
targernum = nums[0]
#此时有1个人守旗
cnt = 1
#开始进行夺旗
for i in nums[1:len(nums)]:
#当是自己人时加入守旗,人数加1
if targernum == i:
cnt += 1
#否则进行夺旗,夺旗者进行一次攻击
else:
cnt -= 1
#守旗者受攻击后若人数为0时则夺旗者夺旗成功
if cnt == 0:
targernum = i
cnt = 1
return targernum
首先,a是数组nums的众数时,那么当nums分为nums[left,mid],nums[mid+1,right]时,a必是其中之一的众数,那么我们去寻找a时,只需要找到子数组的众数,如果相等则直接返回,如果不相等那么则比较两个众数在nums中出现的次数,然后返回这个较大的值。
时间复杂度:O(nlogn)
空间复杂度:O(logn)
class Solution(object):
def majorityElement(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
left = 0
right = len(nums)-1
def majorityElement_rec(left,right):
if left == right:
return nums[left]
mid = (left + right)/2
#找出左边的众数
left = majorityElement_rec(left,mid)
#找出右边的众数
right = majorityElement_rec(mid+1,right)
#如果相等则直接返回这个众数
if left == right:
return left
#否则的话比较二者出现的次数
left_count = nums.count(left)
right_count = nums.count(right)
if left_count > right_count:
return left
else:
return right
return majorityElement_rec(left,right)
这题用分治显然没必要,图一乐了解就好。