数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
示例 1:
输入: [1, 2, 3, 2, 2, 2, 5, 4, 2]
输出: 2
限制:
1 <= 数组长度 <= 50000
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/shu-zu-zhong-chu-xian-ci-shu-chao-guo-yi-ban-de-shu-zi-lcof
暴力方法
class Solution:
def majorityElement(self, nums: List[int]) -> int:
if len(nums)==1:
return nums[0]
freq_dict={}
lens = len(nums)>>1
for i in nums:
if i not in freq_dict.keys():
freq_dict[i]=1
else:
freq_dict[i]+=1
if freq_dict[i]>lens:
pos = i
break
return pos
因为超过一半,所以排序后中位数还是这个众数
class Solution:
def majorityElement(self, nums: List[int]) -> int:
nums = sorted(nums)
mid = len(nums)>>1
return(nums[mid])
题解里的很高级的投票法,假设随便遍历到的数是那个众数,投+1票;不同于这个数的投-1票。当投票归零时再随便设别的为众数。这样做是因为,如果设到的数刚好是这个众数,归零干掉的数中有一半是众数,则这个众数仍然是剩下数中的众数。如果设到的数不是这个众数,则归零干掉的数大部分都是别的数,剩下的数更多是这个众数。所以不管怎样,剩下的数中没有改变这个数是众数的身份。因此,持续归零简化计算。
class Solution:
def majorityElement(self, nums: List[int]) -> int:
votes = 0
for num in nums:
if votes == 0: x = num
votes += 1 if num == x else -1
return x
剑指offer中:
题目描述
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
hash:
# -*- coding:utf-8 -*-
class Solution:
def MoreThanHalfNum_Solution(self, numbers):
# write code here
if not numbers:
return 0
num_dict = {}
lens = len(numbers)>>1
for num in numbers:
if num not in num_dict:
num_dict[num]=1
else:
num_dict[num]+=1
if num_dict[num]>lens:
return num
return 0
排序和投票要多加一个判断是否存在,不存在返回0
# -*- coding:utf-8 -*-
class Solution:
def MoreThanHalfNum_Solution(self, numbers):
# write code here
#投票法
if not numbers:
return 0
vote = 0
mid = len(numbers)>>1
for num in numbers:
if vote==0:
x = num
vote+=1 if num==x else -1
count=0
for num in numbers:
if num==x:
count+=1
if count>mid:
return x
return 0
排序:
# -*- coding:utf-8 -*-
class Solution:
def MoreThanHalfNum_Solution(self, numbers):
# write code here
if not numbers:
return 0
mid = len(numbers)>>1
numbers = sorted(numbers)
x = numbers[mid]
count = 0
for num in numbers:
if num==x:
count+=1
if count>mid:
return x
return 0