(11)LeetCode 239. 滑动窗口最大值

LeetCode 239. 滑动窗口最大值

题目描述

给你一个整数数组 nums 和一个大小为 k 的滑动窗口,窗口从数组的最左侧移动到最右侧,每次只向右移动一位。返回每个窗口中的最大值。

示例:

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

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

解题思路

核心思想: 使用双端队列(deque)维护一个单调递减的下标序列。

  • 队列中存储的是数组下标,且保证这些下标对应的元素值从队首到队尾严格递减。
  • 队首元素对应的值就是当前滑动窗口的最大值。

算法步骤:

  1. 遍历数组,当前下标 i 作为窗口的右边界。
  2. 维护递减性 :若当前元素 nums[i] 大于等于队尾元素对应的值,则队尾元素不可能成为后续窗口的最大值,将其弹出。
  3. 将当前下标 i 从队尾入队。
  4. 移除过期下标 :计算窗口左边界 left = i - k + 1,若队首下标小于 left,说明该元素已滑出窗口,从队首弹出。
  5. 记录答案 :当 left >= 0 时,当前窗口已完整,队首下标对应的值即为最大值,存入结果数组 ans[left]

代码实现(C++)

cpp 复制代码
class Solution {
public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        int n = nums.size();
        deque<int> q;               // 存储下标,保证值递减
        vector<int> ans(n - k + 1); // 结果数组

        for (int i = 0; i < n; ++i) {
            // 1. 维护队列单调递减
            while (!q.empty() && nums[q.back()] <= nums[i])
                q.pop_back();
            q.push_back(i);

            // 2. 移除窗口外的元素
            int left = i - k + 1;
            if (q.front() < left)
                q.pop_front();

            // 3. 当窗口完整时记录最大值
            if (left >= 0)
                ans[left] = nums[q.front()];
        }
        return ans;
    }
};

复杂度分析

  • 时间复杂度: O(n)
    每个元素最多入队一次、出队一次,总操作次数为 O(n)。
  • 空间复杂度: O(n)
    双端队列最多存储 k 个元素,结果数组需要 O(n - k + 1) 空间。

手动模拟示例

nums = [1,3,-1,-3,5,3,6,7], k = 3 为例:

i nums[i] 队列状态(存下标) 窗口范围 最大值
0 1 [0] - -
1 3 弹出 0,队列 [1] - -
2 -1 队列 [1,2] [0~2] 3
3 -3 队列 [1,2,3] [1~3] 3
4 5 弹出 3,2,1,队列 [4] [2~4] 5
5 3 队列 [4,5] [3~5] 5
6 6 弹出 5,4,队列 [6] [4~6] 6
7 7 弹出 6,队列 [7] [5~7] 7

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

关键点总结

  • 队列中存储的是下标,而不是元素值,方便判断元素是否滑出窗口。
  • 双端队列从队尾 维护单调性(淘汰较小值),从队首淘汰过期值。
  • 每个窗口的最大值就是队首元素对应的值,获取时间为 O(1)。
相关推荐
自我意识的多元宇宙5 小时前
树与二叉树--二叉树的存储结构
数据结构
白羊by7 小时前
YOLOv1~v11 全版本核心演进总览
深度学习·算法·yolo
墨尘笔尖8 小时前
最大最小值降采样算法的优化
c++·算法
自我意识的多元宇宙10 小时前
二叉树的遍历和线索二叉树--二叉树的遍历
数据结构
qq_50242899010 小时前
清华大学与微软亚洲研究院出品:Kronos 本地部署教程
数据结构·python·金融量化·kronos开源模型
white-persist10 小时前
【vulhub shiro 漏洞复现】vulhub shiro CVE-2016-4437 Shiro反序列化漏洞复现详细分析解释
运维·服务器·网络·python·算法·安全·web安全
FL162386312911 小时前
基于C#winform部署软前景分割DAViD算法的onnx模型实现前景分割
开发语言·算法·c#
baizhigangqw12 小时前
启发式算法WebApp实验室:从搜索策略到群体智能的能力进阶
算法·启发式算法·web app
C雨后彩虹12 小时前
最多等和不相交连续子序列
java·数据结构·算法·华为·面试
cpp_250113 小时前
P2347 [NOIP 1996 提高组] 砝码称重
数据结构·c++·算法·题解·洛谷·noip·背包dp