题目
Given an integer array of size n,
find all elements that appear more than ⌊ n/3 ⌋ times.
The algorithm should run in linear time and in O(1) space.
题目很简短,给定一个包含n个数字的数组,找出所有出现次数超过 ⌊ n/3 ⌋ 次的数。要求O(n)时间复杂度和O(1)空间复杂度。
解析
- 因为要求超过 ⌊ n/3 ⌋ 次,所以最多只有两个数
- 可以参考找出出现次数大于一半容量的数的解法:majority-vote-algorithm
- 根据以上两点,可以设两个变量,两个计数变量,利用投票算法,得到最后的候选数,为什么是候选数呢,因为数组并未保证一定有这种数和数量。所以还需要再一次遍历检查候选数是否符合要求。
复杂度分析
两次遍历数组,时间复杂度为O(n),空间复杂度为O(1)
代码
public List<Integer> majorityElement(int[] nums) {
List<Integer> res = new ArrayList();
if(nums == null || nums.length == 0) return res;
int candidate1 = 0, candicate2 = 1; //随便赋值就可以
int cnt1 = 0, cnt2 = 0;
for(int num : nums){
if(num == candidate1){
cnt1 ++;
}else if(num == candicate2){
cnt2 ++;
}else if(cnt1 == 0){
cnt1 ++;
candidate1 = num;
}else if(cnt2 == 0){
cnt2 ++;
candicate2 = num;
}else{
cnt1 --;
cnt2 --;
}
}
cnt1 = cnt2 = 0;
for(int num: nums){
if(num == candidate1){
cnt1 ++;
}else if(num == candicate2){
cnt2 ++;
}
}
if(cnt1 > nums.length / 3){
res.add(candidate1);
}
if(cnt2 > nums.length / 3){
res.add(candicate2);
}
return res;
}
网友评论