数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
示例 1:
输入: [1, 2, 3, 2, 2, 2, 5, 4, 2]
输出: 2
限制:
1 <= 数组长度 <= 50000
思路1 排序法
有题目可以知道,数组的中位数即为所求。
因此,问题可以转换为中位数问题,对数组进行排序,取nums[n/2]即可。
代码
class Solution:
def majorityElement(self, nums: List[int]) -> int:
nums.sort()
if len(nums) <=1:
return nums[0]
return nums[int(len(nums)/2)]
时间复杂度分析
快速排序算法时间复杂度为O(Nlog2N)
空间复杂为O(log2N)~O(N)
结果
思路2 显而易见的哈希表统计法
遍历数组,把每个值出现的次数存储到一个哈希表中。根据题目,选取出现次数最多的数值,即为所求。时间复杂度O(N),空间复杂度O(N).
代码
class Solution:
def majorityElement(self, nums: List[int]) -> int:
nums_dict = {}
max_count = 0
for num in nums:
if nums_dict.__contains__(num):
nums_dict[num] += 1
else:
nums_dict.update({num: 1})
if nums_dict[num] > max_count:
max_count = nums_dict[num]
max_num = num
return max_num
结果
思路3 摩尔投票法
之前从未听说过的算法,网上找到的绝大多数资料都是使用摩尔投票法求众数,也就是这道题,她的思路简单来说就是,遍历数组,设此时的第一个数就是众数,则所有众数权值是1,其他所有数权值是-1. 每遍历一个数,就把该数的权值加入当前遍历的权值中。当和为0时,更新众数。最后所得的众数即为所求。
(表达不清楚,更加详细生动的说明见这位大佬的题解)
代码
class Solution:
def majorityElement(self, nums: List[int]) -> int:
votes = 0
for num in nums:
if votes == 0:
max_num = num
if num == max_num:
votes += 1
else:
votes -= 1
return max_num
结果
Note
if num == max_num:
votes += 1
else:
votes -= 1
可以简化为
votes += 1 if num == max_num else -1