力扣热门100题之滑动窗口最大值【困难】

题目描述

给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。

返回 滑动窗口中的最大值 。

示例 1:

输入:nums = [1,3,-1,-3,5,3,6,7], k = 3

输出:[3,3,5,5,6,7]

解释:

滑动窗口的位置 最大值

1 3 -1\] -3 5 3 6 7 3 1 \[3 -1 -3\] 5 3 6 7 3 1 3 \[-1 -3 5\] 3 6 7 5 1 3 -1 \[-3 5 3\] 6 7 5 1 3 -1 -3 \[5 3 6\] 7 6 1 3 -1 -3 5 \[3 6 7\] 7

示例 2:

输入:nums = [1], k = 1

输出:[1]

提示:

解法1 暴力破解

js 复制代码
/**
 * @param {number[]} nums
 * @param {number} k
 * @return {number[]}
 */
var maxSlidingWindow = function(nums, k) {
    let left=0;
    let right=k;
    let max=0;
    const res=[]
    for(let i=0;i<k;i++){
        max=Math.max(max,nums[i]);
    }
    res.push(max)
    while(right<nums.length){
        //不断地右移
        left++;
        right++;
        max=maxFunc(left,right,nums);
        res.push(max);
    }
    return res;
};
function maxFunc(start,end,numArr){
    let max=numArr[start];
    while(start<end){
        max=Math.max(max,numArr[start]);
        start++;
    }
    return max;
}

执行情况

解法2 滑动窗口+记录最值

js 复制代码
/**
 * @param {number[]} nums
 * @param {number} k
 * @return {number[]}
 */
var maxSlidingWindow = function(nums, k) {
    const res=[]
    let max=0;
    for(let i=0;i<k;i++){
        max=Math.max(max,nums[i]);
    }
    res.push(max);
    // left= i-k; //移出的i-k-1
    for(let i=k;i<nums.length;i++){
        if(nums[i-k]==max){
            //移出了最大的值
            max=maxFunc(i-k+1,i+1,nums);
        }
        if(nums[i]>max){
             max=nums[i];
        }
        res.push(max);
    }
    return res;
};
function maxFunc(start,end,numArr){
    let max=numArr[start];
    while(start<end){
        max=Math.max(max,numArr[start]);
        start++;
    }
    return max;
}

解法3 单调队列

js 复制代码
/**
 * @param {number[]} nums
 * @param {number} k
 * @return {number[]}
 */
var maxSlidingWindow = function(nums, k) {
    const n = nums.length;
    const q = [];
    for(let i=0;i<k;i++){
        while(q.length&&nums[i]>=nums[q[q.length-1]]){
          q.pop()
        }
        q.push(i)
    }
    const res=[nums[q[0]]];
    for(let i=k;i<n;i++){
        while(q.length&&nums[i] >= nums[q[q.length-1]]){
            q.pop();
        }
        q.push(i)
        while(q[0]<=i-k){
        q.shift()
        } 
        res.push(nums[q[0]])
    }
    return res;
};

执行情况

相关推荐
im_AMBER1 小时前
Leetcode 78 识别数组中的最大异常值 | 镜像对之间最小绝对距离
笔记·学习·算法·leetcode
鼾声鼾语1 小时前
matlab的ros2发布的消息,局域网内其他设备收不到情况吗?但是matlab可以订阅其他局域网的ros2发布的消息(问题总结)
开发语言·人工智能·深度学习·算法·matlab·isaaclab
其美杰布-富贵-李1 小时前
HDF5文件学习笔记
数据结构·笔记·学习
LYFlied2 小时前
【每日算法】LeetCode 25. K 个一组翻转链表
算法·leetcode·链表
Swizard2 小时前
别再迷信“准确率”了!一文读懂 AI 图像分割的黄金标尺 —— Dice 系数
python·算法·训练
s09071362 小时前
紧凑型3D成像声纳实现路径
算法·3d·声呐·前视多波束
可爱的小小小狼2 小时前
算法:二叉树遍历
算法
d111111111d3 小时前
在STM32函数指针是什么,怎么使用还有典型应用场景。
笔记·stm32·单片机·嵌入式硬件·学习·算法
明洞日记3 小时前
【数据结构手册008】STL容器完全参考指南
开发语言·数据结构·c++
kingmax542120083 小时前
《数据结构C语言:单向链表-链表基本操作(尾插法建表、插入)》15分钟试讲教案【模版】
c语言·数据结构·链表