给定一个大小为 n 的数组,找出其中所有出现超过 ⌊ n/3 ⌋ 次的元素。
说明: 要求算法的时间复杂度为 O(n),空间复杂度为 O(1)。
示例 1:
输入: [3,2,3]
输出: [3]
示例 2:
输入: [1,1,1,3,3,2,2,2]
输出: [1,2]
思路:
超过n/3的数最多只能有两个。先选出两个候选人A,B。 遍历数组,分三种情况:
1.如果投A(当前元素等于A),则A的票数++;
2.如果投B(当前元素等于B),B的票数++;
3.如果A,B都不投(即当前与A,B都不相等),那么检查此时A或B的票数是否减为0:
3.1 如果为0,则当前元素成为新的候选人;
3.2 如果A,B两个人的票数都不为0,那么A,B两个候选人的票数均减一;
遍历结束后选出了两个候选人,但是这两个候选人是否满足>n/3,还需要再遍历一遍数组,找出两个候选人的具体票数。
class Solution {
public List<Integer> majorityElement(int[] nums) {
List<Integer> res=new ArrayList<>();
if(nums==null || nums.length==0)
return res;
int candidateA=nums[0];
int candidateB=nums[0];
int countA=0,countB=0;
for(int num:nums)
{
if(num==candidateA)
countA++;
else if(num==candidateB)
countB++;
else if(countA==0)
{
countA++;
candidateA=num;
}
else if(countB==0)
{
countB++;
candidateB=num;
}
else
{
countA--;
countB--;
}
}
countA=countB=0;
for(int num:nums)
{
if(num==candidateA)
countA++;
else if(num==candidateB)
countB++;
}
if(countA>nums.length/3)
res.add(candidateA);
if(countB>nums.length/3)
res.add(candidateB);
return res;
}
}