剑指offer-python:36.数组中出现次数超过一半的数字

题目:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
例如输入一个长度为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

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值