229 求众数 II(摩尔投票法)

1. 问题描述:

给定一个大小为 n 的整数数组,找出其中所有出现超过 ⌊ n / 3 ⌋ 次的元素。进阶:尝试设计时间复杂度为 O(n)、空间复杂度为 O(1)的算法解决此问题。

示例 1:

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

示例 2:

输入:nums = [1]
输出:[1]

示例 3:

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

提示:
1 <= nums.length <= 5 * 10 ^ 4
-10 ^ 9 <= nums[i] <= 10 ^ 9

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/majority-element-ii

2. 思路分析:

这道题目可以使用摩尔投票法的扩展进行求解,因为要求超过 ⌊ n / 3 ⌋ 次的元素,所以我们可以看成有2个仓库r1,r2,仓库元素的数目为c1,c2,摩尔投票法使用的是抵消的思想,遍历的元素与当前仓库中所有元素都不相等的时候那么所有仓库的元素数目都要减去1,如果与某个仓库中的元素相等的时候那么对应仓库的元素数目加1,如果仓库为空的时候那么可以将当前元素放入到仓库中,并且对应仓库的元素数目加1,最后遍历一下仓库中记录的元素(如果某个元素次数超过⌊ n / k ⌋那么它必然会存到某个仓库中,并且声明k - 2个仓库即可),统计一下nums中出现与仓库中元素相等的数目,最后判断一下元素的数目是否超过 n / k(这道题目的k = 3) ,如果满足那么说明当前元素是符合条件的。

3. 代码如下:

import collections
from typing import List


class Solution:
    def majorityElement(self, nums: List[int]) -> List[int]:
        # r1, r2分别表示两个仓库, c1, c2表示两个仓库对应的数目
        r1, r2, c1, c2 = None, None, 0, 0
        for i in range(len(nums)):
            if c1 and nums[i] == r1:
                c1 += 1
            elif c2 and nums[i] == r2:
                c2 += 1
            elif c1 == 0:
                r1 = nums[i]
                c1 += 1
            elif c2 == 0:
                r2 = nums[i]
                c2 += 1
            else:
                c1 -= 1
                c2 -= 1
        c1, c2 = 0, 0
        for i in range(len(nums)):
            if nums[i] == r1: c1 += 1
            elif nums[i] == r2: c2 += 1
        res = list()
        n = len(nums)
        if c1 > n // 3: res.append(r1)
        if c2 > n // 3: res.append(r2)
        return res

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值