🌈【LeetCode.229 众数】- JavaScript =>摩尔投票法+Map

505 阅读2分钟

「这是我参与11月更文挑战的第1天,活动详情查看:2021最后一次更文挑战


说明:文章部分内容及图片出自网络,如有侵权请与我本人联系(主页有公众号:小攻城狮学前端)

作者:小只前端攻城狮、 主页:小只前端攻城狮的主页、 来源:掘金

GitHub:P-J27、 CSDN:PJ想做前端攻城狮

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


题意描述

给定一个大小为 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的元素,就是上面分析的思路。

具体的步骤实现

  1. 把两个众数和其它分成三堆
  2. 每次拿走不同的三个数
  3. 剩下的可能是众数
  4. 扫描所有数据验证大于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
};

感谢阅读,希望能对你有所帮助,文章若有错误或者侵权,可以在评论区留言或在我的主页添加公众号联系我。

写作不易,如果觉得不错,可以「点赞」+「评论」 谢谢支持❤