力扣热门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;
};

执行情况

相关推荐
孞㐑¥41 分钟前
算法——BFS
开发语言·c++·经验分享·笔记·算法
月挽清风1 小时前
代码随想录第十五天
数据结构·算法·leetcode
XX風1 小时前
8.1 PFH&&FPFH
图像处理·算法
NEXT061 小时前
前端算法:从 O(n²) 到 O(n),列表转树的极致优化
前端·数据结构·算法
代码游侠2 小时前
学习笔记——设备树基础
linux·运维·开发语言·单片机·算法
想进个大厂2 小时前
代码随想录day37动态规划part05
算法
sali-tec2 小时前
C# 基于OpenCv的视觉工作流-章22-Harris角点
图像处理·人工智能·opencv·算法·计算机视觉
子春一2 小时前
Flutter for OpenHarmony:构建一个 Flutter 四色猜谜游戏,深入解析密码逻辑、反馈算法与经典益智游戏重构
算法·flutter·游戏
人道领域2 小时前
AI抢人大战:谁在收割你的红包
大数据·人工智能·算法
TracyCoder1233 小时前
LeetCode Hot100(34/100)——98. 验证二叉搜索树
算法·leetcode