题目:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
解析:1)字典直接实现;2)第二种:( Majority Element。找出数组中出现超过一半的元素)波义尔摩尔投票算法。
字典就不做了,几行即可。
主要集中在第二种:
整个过程想象成一次投票选举
投票规则:大屏幕上只允许出现一位候选人。如果选举人投的票不是当前候选人,那么让当前候选人票-1,如果是,则+1。
OK,我们现在把所有数组的元素当成是选举人举出的号牌。我们先考虑最极端的情况:最后的winner
以一票之差险胜。也就是元素出现的次数为n//2+1
。这种情况是如何出现的呢,假设数组是这样的:
[7, 7, 7, 7, 1, 2, 3]
没有投7的选举人假设在一开始知道了最有潜力的winner
即7号,那么他们‘同仇敌忾’,将-1的票都投在了7号上,这种情况7号一直处于大屏幕中,没有更换过候选人。但是最后也没能打败7号,因为7号最后还保留一票。
另外一种非极端的情况,没有投7的选举人产生了‘内讧’:
[7, 1, | 2, 3, | 7, 7, 7]
首先7号得到一票,然后被1号干掉,接着2号称为候选人,被3号干掉。3号的票浪费在了‘自己人’身上,即‘我们中出了一个叛徒’。就算团结起来都干不过7号,所以winner
还是7号。
代码:遍历整个数组,下一个和上一个做比较,相同就+1,不同就-1,当计数器==0时候,赋值当前的投票数字。
class Solution:
def majorityElement(self, nums):
count = 0
candidate = None
for num in nums:
if count == 0:
candidate = num
count += (1 if num == candidate else -1)
return candidate