LeetCode229-求众数II

这两天想到一个冷笑话,迫不及待想和大家分享

在外面买鸡蛋,教大家如何区分土鸡蛋和洋鸡蛋

把鸡蛋打破,蛋清越透明说明这鸡蛋是土鸡蛋

。。。

不好笑也要笑<<


题目:

给定一个大小为 n 的数组,找出其中所有出现超过 ⌊ n/3 ⌋ 次的元素。

说明: 要求算法的时间复杂度为 O(n),空间复杂度为 O(1)。

示例 1:

输入: [3,2,3]
输出: [3]

示例 2:

输入: [1,1,1,3,3,2,2,2]
输出: [1,2]

思路:

这题我刚开始是真的没思绪,因为空间复杂度的限制,我们只能定义变量。可是数组有n个元素,怎么用变量来找啊。看了网上的思路后才发觉自己有个概念没有理解,就是摩尔投票法。什么是摩尔投票法呢?定义如下:

一组数字序列中出现次数大于总数1/2的数字(并且假设这个数字一定存在),显然这个数字只可能有一个

本题是要我们找出其中所有出现超过 ⌊ n/3 ⌋ 次的元素,那定义可以变化为:

一组数字序列中出现次数大于总数1/3的数字(并且假设这个数字一定存在),显然这个数字最多有2个

这个定义理解了,那前面我们提到的疑惑就解决了。只需要定义两个变量,分别记录众数即可。

当然了,光有定义可不行,还得知道如何找出这些众数才算数,这时候又不得不提到摩尔投票法的核心思想了,如下所示:

当一个数的重复次数超过数组长度的一半,每次将两个不相同的数删除,最终剩下的就是要找的数

上图就是查找出现次数大于总数1/2的数字过程,核心思路就是不断抵消对抗。那么本题中如何找出其中所有出现超过 ⌊ n/3 ⌋ 次的元素呢?上面也提到了,我们可以设立两个cand1,cand2变量分别记录可能是众数的数字,num1和num2分别代表相应数字出现的次数。类比找出出现次数大于总数1/2的数字过程,我们此处是如果cand1,cand2与当前数字不一样,才会共同抵消,否则不会抵消。过程如下:

最后还有个特殊情况,就是比如:[A, B, C]的抵消阶段,最后得到的结果是 [C,1],C候选人的票数也未能超过一半的票数。所以,我们在代码的后面还需要加个计数操作,如果当前cand对应的num确实是超过了1/2或者1/3才能说,它真的是我们要找的众数。代码如下:

class Solution(object):
    def majorityElement(self, nums):
        """
        摩尔投票法
        :type nums: List[int]
        :rtype: List[int]
        """
        if len(nums) == 0:
            return []
        cand1, cand2 = nums[0], nums[0]
        num1, num2 = 0, 0
        result = []
        for i in nums:
            if cand1 == i:
                num1 += 1
                continue
            if cand2 == i:
                num2 += 1
                continue
            if num1 == 0:
                cand1 = i
                num1 += 1
                continue
            if num2 == 0:
                cand2 = i
                num2 += 1
                continue
            num1 -= 1
            num2 -= 1
        print("can1:{0}, can2:{1}".format(cand1, cand2))
        if cand1 == cand2:
            return [cand1]
        num1, num2 = 0, 0
        for i in nums:
            if cand1 == i:
                num1 += 1
            if cand2 == i:
                num2 += 1
        if num1 > len(nums)/3:
            result.append(cand1)
        if num2 > len(nums)/3:
            result.append(cand2)
        return result


if __name__ == "__main__":
    nums = [1]
    result = Solution().majorityElement(nums)
    print(result)

执行效率在70%吧!

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学习的学习者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值