代码随想录算法训练营第十三天|239. 滑动窗口最大值 347.前 K 个高频元素(JS写法)

文章介绍了两种解决滑动窗口问题的方法,包括使用for循环和单调队列优化的求最大值算法,以及利用哈希表和map处理前k个高频元素的问题。还提到了JS数组map的用法和可能的大根堆解决方案。
摘要由CSDN通过智能技术生成

239 滑动窗口最大值

题目链接/文章讲解/视频讲解:https://programmercarl.com/0239.%E6%BB%91%E5%8A%A8%E7%AA%97%E5%8F%A3%E6%9C%80%E5%A4%A7%E5%80%BC.html
方法一:自己写的,但是执行很长的测试用例会超时,一开始我写的是while循环,有点没搞懂,后来在何包蛋的帮助下改成了for循环就对了。

var maxSlidingWindow = function(nums, k) {
    let res = [];
    //这里i的范围需要-k,因为i走不到最后一个
    for(let i = 0;i<=nums.length - k;i++){
        let j = i+k-1;
        let p = i;
        // while(p<=j){
        //     let max = nums[p];
        //     let temp = nums[++p];
        //     if(temp > max){
        //         max = temp;
        //     }
        let max = nums[i];
        for(let p = i+1;p<=j;p++){
            if(nums[p] > max){
                max = nums[p];
            }
        }
        res.push(max);
            // console.log(res);       
        // }
    
    }
    return res;
}

时间复杂度O(n*k)
方法二:单调队列:单调递减的双端队列
注意,往单调队列里push进去的是索引,而不是元素

/**
 * @param {number[]} nums
 * @param {number} k
 * @return {number[]}
 */
var maxSlidingWindow = function (nums, k) {
    const q = [];//单递减的双端队列
    const ans = [];//最后的返回结果
    for (let i = 0; i < nums.length; i++) {//循环nums
        //当进入滑动窗口的元素大于等于队尾的元素时 不断从队尾出队,
        //直到进入滑动窗口的元素小于队尾的元素,以保证单调递减的性质
        while (q.length && nums[i] >= nums[q[q.length - 1]]) {
            q.pop();
        }
        q.push(i);//元素的索引入队
        while (q[0] <= i - k) {//队头元素已经在滑动窗口外了,移除队头元素
            q.shift();
        }
        //当i大于等于k-1的时候,单调递减队头就是滑动窗口的最大值
        if (i >= k - 1) ans.push(nums[q[0]]);
    }
    return ans;
};

参考题解:
在这里插入图片描述

347 前k个高频元素

题目链接/文章讲解/视频讲解:https://programmercarl.com/0347.%E5%89%8DK%E4%B8%AA%E9%AB%98%E9%A2%91%E5%85%83%E7%B4%A0.html
方法一:哈希表
哈希表是无序的,因此必须转成数组,再截取前k个。

/**
 * @param {number[]} nums
 * @param {number} k
 * @return {number[]}
 */
var topKFrequent = function(nums, k) {
    const map = new Map();
    for(let i=0;i<nums.length;i++){
        if(map.has(nums[i])){
            map.set(nums[i],map.get(nums[i])+1);
        }else{
            map.set(nums[i],1);
        }
    }
    //nums.forEach(n => {
    //    map.set(n, map.has(n) ? map.get(n)+1 : 1)
    //})
    // 首先将字典转成数组,然后对数组中的第二个元素(频度)从大到小排序
    //按照value进行排序
    const list = Array.from(map).sort((a, b) => b[1] - a[1])
    //console.log(map);  Map(3) { 1 => 3, 2 => 2, 3 => 1 }
    //console.log(list);   [ [ 1, 3 ], [ 2, 2 ], [ 3, 1 ] ]
    // 截取频率前k高的元素
    //console.log(list.slice(0, k));  [ [ 1, 3 ], [ 2, 2 ] ]
    return list.slice(0, k).map(n => n[0]);
    //return list.slice(0, k).map(function(n){
    //    return n[0];
    //})
};

JS数组高阶函数map的用法:https://blog.csdn.net/dyk11111/article/details/131247932
方法二:大根堆(待补充)

  • 9
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值