229-Majority-Element-II
Last updated
Was this helpful?
Last updated
Was this helpful?
给定一个大小为 n 的数组,找出其中所有出现超过 ⌊ n/3 ⌋ 次的元素。 说明: 要求算法的时间复杂度为 O(n),空间复杂度为 O(1)。
测试用例:
示例 1: 输入: [3,2,3] 输出: [3] 示例 2: 输入: [1,1,1,3,3,2,2,2] 输出: [1,2]
这道题呢,难就难在要求空间复杂度为O(1),否则直接用hashmap统计一遍就可得出答案。
所以正确的做法是使用摩尔投票法。这个摩尔投票呢,我也解释不清楚,好像是似懂非懂的感觉。对于长度为n的数组,个数超过⌊ n/k ⌋的众数最多有k-1个。因为试想以下,假设有k个众数,每个众数都>⌊ n/k ⌋,那么最后数的个数和就超过n了,显然不成立。
所以对于k=3,众数最多有2个,但是不一定有两个,因为有可能没有产生众数。对于k=3,所以我们需要选取两个候选者A、B,当第三个数不等于A或B,且A和B的个数都不为零时,表示这个人把票投个第三者了,A和B的票数都需要减1。当A或B的票数减为0时,我们就可以更新候选者了。最后剩下了两个数,就有可能成为众数。
怎么说呢?这个摩尔投票感觉就是在相互对抗,对于两个候选者,如果它们的票数都被别的选票对抗完了,表示它们在当前情况下,它们已经不可能成为候选人了,要选新人了。剩下的一定是票数最多的人。
摩尔投票法我还是不是很懂啊,对于只有一个众数的问题,我是明白了,但是我不明白的是求两个众数时,为什么第三张票不同时,两个众数的票数都要减1呢?