题目来源:https://leetcode-cn.com/problems/majority-element-ii/description/
题目描述:
本题是在上篇博客题目的难度上做了略微提升,上题详见:https://blog.csdn.net/qq_39241239/article/details/82871294
算法描述:相信你已经阅读了上一篇博客,那么就好办了。本题有两种效率较高的做法。
第一种:摩尔投票法:
题目给了我们一个 nums array, 让我们找出所有 数量超过 n/3 的众数。这一题与 众数之一 的区别在于,众数之一 只要找到一个 众数大于 n/2 的就可以。这一题要找到所有的数量 大于n/3的众数,其实,最多也就会有两个 大于n/3 的众数。因为可能会出现两个众数,而且是要数量 大于n/3 的,所以我们需要遍历两次nums array。
第一次遍历 需要找出数量出现最多的 两个数字;
第二次遍历 需要找出准确的出现次数,因为第一次遍历可能会漏掉一些次数;
最后,要检查次数大于 n/3 的 才算众数。
代码如下:
class Solution {
public List<Integer> majorityElement(int[] nums) {
List<Integer> list = new ArrayList<Integer>();
int result1 = 0, result2 = 0, count1 = 0, count2 = 0;
for (int x : nums) {
if (x == result1)
count1++;
else if (x == result2)
count2++;
else if (count1 == 0) {
result1 = x;
count1 = 1;
} else if (count2 == 0) {
result2 = x;
count2 = 1;
} else {
count1--;
count2--;
}
}
count1 = count2 = 0;
for(int x : nums) {
if(x == result1)
count1++;
if(x == result2)
count2++;
}
if(count1 > (nums.length/3))
list.add(result1);
if((count2 > (nums.length/3)) && (result2!=result1))
list.add(result2);
return list;
}
}
第二种:先排序,然后再遍历
class Solution {
public List<Integer> majorityElement(int[] nums) {
int n=nums.length/3,count=1;
List<Integer> result=new ArrayList<>();
Arrays.sort(nums);
for(int i=0;i<nums.length-1;i++){
if(nums[i]==nums[i+1])
count++;
else{
if(count>n)
result.add(nums[i]);
count=1;
}
}
if(count>n && nums.length>0)
result.add(nums[nums.length-1]);
return result;
}
}