(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 numsi 队列状态(存下标) 窗口范围 最大值
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)。
相关推荐
月华路6 小时前
G1 GC 对数组与大对象(Humongous)的处理
java·jvm·算法
我想走路带风6 小时前
LRU和最长前缀和(计算机网络算法)
计算机网络·算法
M78佐菲6 小时前
Linux学习笔记:进程
linux·笔记·学习·算法
徐小夕8 小时前
表格、文档、甘特、大屏、表单一站打通:pxcharts超级表格4.0正式上线!
前端·算法·github
Xin7708 小时前
LeetCode 23.合并 K 个升序链表(分治递归)
leetcode
TechLee8 小时前
跨语言加解密总对不上?这个纯 Go 神库让 AES/RSA 与 PHP、Java 100% 互通
java·后端·算法
月华路10 小时前
G1 新生代对象晋升老年代:实现机制与 GC 日志
java·jvm·算法
万法若空10 小时前
排列组合恒等式
c++·算法
Nil20811 小时前
leetcode 105从前序和中序遍历序列构造二叉树
算法·leetcode·职场和发展
一直C11 小时前
【数据结构】哈希表+算法复杂度与经典排序查找(C语言)
java·linux·开发语言·数据结构·算法·ubuntu·散列表