Leetcode摩尔投票

摩尔投票

169 多数元素

在这里插入图片描述
知识点:摩尔投票
结论:
如果至多选一个代表,那他的票数至少要超过一半(⌊ 1/2 ⌋)的票数;
如果至多选两个代表,那他们的票数至少要超过 ⌊ 1/3 ⌋ 的票数;
如果至多选m个代表,那他们的票数至少要超过 ⌊ 1/(m+1) ⌋ 的票数。
碰到这样的问题,而且要求达到线性的时间复杂度以及常量级的空间复杂度,直接套上摩尔投票法

class Solution:
    def majorityElement(self, nums: List[int]) -> int:
        '''
        # 法1 哈希表
        n = len(nums)
        hashmap = {}
        for i in nums:
            hashmap[i] = hashmap.get(i, 0)+1
        for key in hashmap:
            if hashmap[key]>n/2:
                return key
        '''

        # 法2 摩尔投票
        n = len(nums)
        count = 1
        candidate = nums[0]
        for i in range(1, n):
            if nums[i]==candidate:
                count += 1
            elif count>=1:  # 不等 计数减1
                count -= 1
            else:  # count == 0
                candidate = nums[i]
                count += 1
        return candidate

229 多数元素 II

在这里插入图片描述
分析:根据摩尔投票法知,最多找两个候选者
注:至多选n(n>1)个候选者时,不能判断每个人的票数是否一定大于1/(n+1),要重新计数

class Solution:
    def majorityElement(self, nums: List[int]) -> List[int]:
        res = []
        n = len(nums)
        cand1,cand2 = 0, 0
        count1, count2 = 0, 0
    
        for num in nums:            
            if count1>0 and num==cand1:  # 是第一个元素
                count1 += 1
            elif count2>0 and num == cand2:  # 是第2个元素
                count2 += 1
            elif count1 == 0: # 第一个候选者还没确定
                cand1 = num
                count1 += 1
            elif count2 == 0:
                cand2 = num
                count2 += 1
            else:   # 不是这两个候选者
                count1 -= 1
                count2 -= 1

        # 重新计数
        rec1 = 0
        rec2 = 0
        for num in nums:
            if count1 >0 and num == cand1:  # >0是回避初始化为0
                rec1 += 1
            elif count2>0 and num == cand2:
                rec2 += 1

        if rec1>n/3:
            res.append(cand1)
        if rec2>n/3:
            res.append(cand2)
        return res
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值