题目
解题思路
假定num1,num2为出现次数大于nums.length/3的两个数。(最多出现两个)
- 遍历 nums, 若出现 num1、num2 中任意一数,计数+1,若都不等,则计数-1.
- 若 num1、num2 有一个计数 < 0,则替换成当前遍历数(更换新的众数)
- 数组可能出现 无众数 或只有 一众数 情况,所以需要再次遍历数组,统计所选众数出现次数,将满足条件(出现次数大于 nums.length / 3 )的数加入返回集合。
Code
class Solution {
public List<Integer> majorityElement(int[] nums) {
List<Integer> lists = new ArrayList<>();
if (nums.length < 2) { // 只有 1 个数则必为众数
for (int i : nums) {
lists.add(i);
}
return lists;
}
int num1 = nums[0], num2 = nums[1]; // 选出两数
int len = nums.length / 3, count1 = 0, count2 = 0;
for (int i = 0; i < nums.length; i++) {
if (num1 == nums[i]) { // 若出现 num1、num2 中任意一数,计数+1
count1++;
continue;
}else if (num2 == nums[i]) {
count2++;
continue;
}else { // 都不等,则计数-1
count1--;
count2--;
}
if (count1 < 0) { // 更换新的众数
num1 = nums[i];
count1 = 1;
count2++; // 确保每次只更换 1 个
}
if (count2 < 0) {
num2 = nums[i];
count2 = 1;
count1++;
}
}
count1 = 0; // 归零,重新计数
count2 = 0;
for (int num : nums) { // 验证次数,符合则加入集合
if (num == num1) {
count1++;
} else if (num == num2) {
count2++;
}
}
if (count1 > len) {
lists.add(num1);
}
if (count2 > len) {
lists.add(num2);
}
return lists;
}
}
代码运行截图