229. 多数元素 II
js
;(function () {
/**
* 229. 多数元素 II
* 给定一个大小为 n 的整数数组,找出其中所有出现超过 ⌊ n/3 ⌋ 次的元素。
*
* 输入:nums = [3,2,3]
* 输出:[3]
*
* 输入:nums = [1]
* 输出:[1]
*
* 输入:nums = [1,2]
* 输出:[1,2]
*
* 进阶:尝试设计时间复杂度为 O(n)、空间复杂度为 O(1)的算法解决此问题。
*/
function majorityElement(nums: number[]): number[] {
// 方法一:摩尔投票法 --- 抵消阶段和计数阶段
// // 分析:
// // 1. 超过 ⌊ n/3 ⌋ 次的元素,则表示返回的数组最多只有 2 个元素。
// // 2. 遍历数组,多方混战。战斗结果一定只有最多两个阵营幸存,其他阵营被歼灭。数组中的数字即代表某士兵所在的阵营。
// if (nums.length < 3) {
// return [...Array.from(new Set(nums))]
// }
// let aArr: number[] = [];
// let bArr: number[] = [];
// for(let i = 0; i < nums.length; i++) {
// let cur = nums[i]
// // 1. 属于AB阵营的兵力,则累加
// if ( aArr.includes(cur)) {
// aArr.push(cur);
// continue;
// }
// if ( bArr.includes(cur)) {
// bArr.push(cur);
// continue;
// }
// // 2. 新兵力不属于AB阵营,则混战
// if(aArr.length > 0 && bArr.length > 0) {
// aArr.pop()
// bArr.pop()
// } else if (aArr.length === 0 ){
// aArr.push(cur)
// } else {
// bArr.push(cur)
// }
// }
// let rtnArr: number[] = [];
// let len = nums.length / 3;
// let count1 = 0;
// let count2 = 0;
// nums.forEach(i => {
// i === aArr[0] && count1++;
// i === bArr[0] && count2++;
// })
// count1 > len && rtnArr.push(aArr[0]);
// count2 > len && rtnArr.push(bArr[0]);
// return rtnArr
// 方法一:摩尔投票法简化版
// // 分析:
// // 1. 超过 ⌊ n/3 ⌋ 次的元素,则表示返回的数组最多只有 2 个元素。
// // 2. 遍历数组,多方混战。战斗结果一定只有最多两个阵营幸存,其他阵营被歼灭。数组中的数字即代表某士兵所在的阵营。
// // if (nums.length < 3) {
// // return [...Array.from(new Set(nums))]
// // }
// // 配对阶段
// let a = nums[0], aCount = 0;
// let b = nums[0], bCount = 0;
// nums.forEach(item => {
// if (a === item) {
// aCount++;
// return
// }
// if (b === item) {
// bCount++;
// return
// }
// if (aCount === 0) {
// a = item;
// aCount++;
// return
// }
// if (bCount === 0) {
// b = item;
// bCount++;
// return
// }
// aCount--;
// bCount--;
// })
// // 计数阶段
// let rtnArr: number[] = [];
// let len = nums.length / 3;
// let count1 = 0;
// let count2 = 0;
// nums.forEach(i => {
// i === a && aCount > 0 && count1++;
// i === b && bCount > 0 && count2++;
// })
// count1 > len && rtnArr.push(a);
// count2 > len && rtnArr.push(b);
// return rtnArr
// 方法二: 遍历法 / new Map()
// new Map -- set: count++, get: count > n/3
type typeObj = {
[prop: string]: number
}
let obj: typeObj = {}
let rtnArr: number[] = []
nums.forEach((item) => {
obj[item] ? obj[item]++ : (obj[item] = 1)
})
for (let k in obj) {
obj[k] > nums.length / 3 ? rtnArr.push(+k) : null
}
return rtnArr
}
let nums = [2, 2, 1, 1, 1, 2, 2]
let nums2 = [3, 2, 3]
let nums3 = [2, 2]
let nums4 = [1]
let nums5 = [0, 0, 0]
// console.log(majorityElement(nums))
// console.log(majorityElement(nums2))
// console.log(majorityElement(nums3))
// console.log(majorityElement(nums4))
console.log(majorityElement(nums5))
})()