「这是我参与11月更文挑战的第1天,活动详情查看:2021最后一次更文挑战」
说明:文章部分内容及图片出自网络,如有侵权请与我本人联系(主页有公众号:小攻城狮学前端)
作者:小只前端攻城狮、 主页:小只前端攻城狮的主页、 来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
题意描述
给定一个大小为 n 的整数数组,找出其中所有出现超过
⌊ n/3 ⌋次的元素。
示例1 :
输入:[3,2,3]
输出:[3]
示例2:
输入:nums = [1]
输出:[1]
分析
首先我们知道,如果一个数字它出现的频率超过总数的1/2,那么出现总的次数会加1,,没有超过的话次数会减一。因此我们最后的次数一定是大于0的。
同理我们来分析,如果一次数字出现的频率超过总数的1/3, 一次去掉3个数字,次数最多扔n/3次,如果一个数字会超过总数的1/3,那么他最后的次数必定也是大于0的。
思路一:摩尔投票法
摩尔投票法原理:3个数相抵消,可以求出次数大于n/3的元素,就是上面分析的思路。
具体的步骤实现
- 把两个众数和其它分成三堆
- 每次拿走不同的三个数
- 剩下的可能是众数
- 扫描所有数据验证大于n/3
var majorityElement = function(nums) {
let len = nums.length,limit = Math.floor(len/3),counta = 0,countb = 0,res = [],
a = nums[0],b
for(const n of nums){
if(n === a) counta++
else if(n ===b)countb++
else if(counta === 0){
a = n
counta++
} else if(countb === 0){
b = n
countb++
}else{
countb--
counta--
}
}
counta = 0,countb = 0
for(const n of nums){
if(n === a)counta++
else if( n ===b )countb ++
}
if(counta>limit)res.push(a)
if(countb>limit)res.push(b)
return res
};
思路二:哈希表(Map)
分析:遍历并且统计每个元素出现的次数,然后遍历哈希表找出符合要求的元素。就是简单模拟一遍呗
var majorityElement = function(nums) {
let count = Math.floor(nums.length/3)
var map = new Map()
let result = []
nums.forEach(item=>{
if(!map.has(item)){
map.set(item,1)
}else{
map.set(item,map.get(item)+1)
}
})
for(let item of map.entries()){
if(item[1]>count){
result.push(item[0])
}
}
return result
};
感谢阅读,希望能对你有所帮助,文章若有错误或者侵权,可以在评论区留言或在我的主页添加公众号联系我。
写作不易,如果觉得不错,可以「点赞」+「评论」 谢谢支持❤