携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第28天,点击查看活动详情
题目(Majority Element II)
链接:https://leetcode-cn.com/problems/majority-element-ii
解决数:801
通过率:53.8%
标签:数组 哈希表 计数 排序
相关公司:google amazon microsoft
给定一个大小为 n 的整数数组,找出其中所有出现超过 ⌊ n/3 ⌋ 次的元素。
示例 1:
输入: nums = [3,2,3]
输出: [3]
示例 2:
输入: nums = [1]
输出: [1]
示例 3:
输入: nums = [1,2]
输出: [1,2]
提示:
1 <= nums.length <= 5 * 104-109 <= nums[i] <= 109
进阶: 尝试设计时间复杂度为 O(n)、空间复杂度为 O(1)的算法解决此问题。
思路
摩尔投票法 原始摩尔投票法的变种:
function majorityElement(nums) {
let cand1, cand2;
let count1 = 0;
let count2 = 0;
let ans = [];
for(let i = 0; i < nums.length; i++) {
if(nums[i] === cand1) {
count1++;
} else if(nums[i] === cand2) {
count2++;
} else if(count1 === 0) {
cand1 = nums[i];
count1++;
} else if(count2 === 0) {
cand2 = nums[i];
count2++;
}else {
count1--;
count2--;
}
}
count1 = count2 = 0;
for(let i = 0; i < nums.length; i++) {
if(nums[i] === cand1) count1++;
if(nums[i] === cand2) count2++;
}
if(count1 > nums.length/3) ans.push(cand1);
if(count2 > nums.length/3) ans.push(cand2);
return ans;
}
or
function majorityElement(nums) {
let cand1, cand2;
let count1 = 0;
let count2 = 0;
let ans = [];
for(let i = 0; i < nums.length; i++) {
if(nums[i] === cand1) {
count1++;
} else if(nums[i] === cand2) {
count2++;
} else if(count1 === 0) {
cand1 = nums[i];
count1++;
} else if(count2 === 0) {
cand2 = nums[i];
count2++;
}else {
count1--;
count2--;
}
}
count1 = count2 = 0;
for(let i = 0; i < nums.length; i++) {
if(nums[i] === cand1) count1++;
if(nums[i] === cand2) count2++;
}
if(count1 > nums.length/3) ans.push(cand1);
if(count2 > nums.length/3) ans.push(cand2);
return ans;
}
之前做过超过一半个数的众数摩尔投票,其实这里思路是一模一样的,只是从两个抵消变成三个抵消。 同理,大于个数的众数,只需要个数进行抵消即可。
每个数抵消一次的时候,最多抵消次,如果个数比它多的数字,一定会留下。
/**
* @param {number[]} nums
* @return {number[]}
*/
var majorityElement = function(nums) {
let numA = undefined, numB = undefined;
let cntA = 0, cntB = 0;
for(const num of nums){
if(num === numA)
cntA++;
else if(num === numB)
cntB++;
else if(numA === undefined){
numA = num;
cntA++;
}else if(numB == undefined){
numB = num;
cntB++;
}else{
cntA--;
cntB--;
if(cntA==0)
numA = undefined;
if(cntB==0)
numB = undefined;
}
}
cntA = cntB = 0;
for(const num of nums){
if(num == numA)
cntA++;
else if(num == numB)
cntB++;
}
const ans = [];
const s = Math.floor(nums.length/3);
if(cntA > s)
ans.push(numA);
if(cntB > s)
ans.push(numB);
return ans;
};