leetcode 229.求众数 II(lc169求众数)

103 阅读1分钟

229.求众数 II(lc169求众数)

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

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

输入: [1,1,1,3,3,2,2,2]
输出: [1,2]
class Solution:
    def majorityElement(self, nums: List[int]) -> List[int]:
        if not nums:
            return []
        n1 = n2 = None
        c1 = c2 = 0
        for num in nums:
            if n1 == num:
                c1 += 1
            elif n2 == num:
                c2 += 1
            elif c1 == 0:
                n1, c1 = num, 1
            elif c2 == 0:
                n2, c2 = num, 1
            else:
                c1, c2 = c1 - 1, c2 - 1
        return [n for n in (n1, n2)
                if nums.count(n) > len(nums) // 3]
"""
Boyer-Moore投票算法,如果存在众数,该算法一定可以找出来。
通俗点说就是从第一个数开始 c = 1,遇到相同的就加 1,遇到不同的就减 1,
减到 0 就 重新换个数重新计数,最后的那个 m 即为所求众数。

数组中至多可能会有2个出现次数超过 ⌊ n/3 ⌋ 的众数
记变量n1, n2为候选众数; c1, c2为它们对应的出现次数
遍历数组,记当前数字为num
若num与n1或n2相同,则将其对应的出现次数加1
否则,若c1或c2为0,则将其置为1,对应的候选众数置为num
否则,将c1与c2分别减1
最后,再统计一次候选众数在数组中出现的次数,若满足要求,则返回之。
"""