滑动时间窗口,找一段区间中的最大值

双端队列(Deque) 维护"可能成为窗口最大值"的候选下标,

队头始终是当前窗口最大值,

每次右移窗口时:

  1. 弹出队头 过期 的下标(< left)
  2. 从队尾剔除 ≤ 新元素的下标
  3. 把新元素下标入队尾
  4. 记录队头值即可

时间 O(n) ,空间 O(k)


代码(int\[\] 版,可直接跑)

java 复制代码
import java.util.*;

public class SlidingWindowMax {

    // 返回每个窗口的最大值列表
    public static List<Integer> maxSlidingWindow(int[] nums, int k) {
        List<Integer> ans = new ArrayList<>();
        Deque<Integer> deq = new ArrayDeque<>(); // 存下标,单调递增

        for (int i = 0; i < nums.length; i++) {
            // 1. 弹出队头过期下标
            while (!deq.isEmpty() && deq.peek() < i - k + 1) {
                deq.poll();
            }
            // 2. 从队尾剔除 ≤ 当前值的候选
            while (!deq.isEmpty() && nums[deq.peekLast()] <= nums[i]) {
                deq.pollLast();
            }
            // 3. 当前下标入队
            deq.offer(i);
            // 4. 窗口形成后记录答案
            if (i >= k - 1) {
                ans.add(nums[deq.peek()]);
            }
        }
        return ans;
    }

    /* ---------- 测试 ---------- */
    public static void main(String[] args) {
        int[] nums = {1, 3, -1, -3, 5, 3, 6, 7};
        int k = 3;
        System.out.println(maxSlidingWindow(nums, k)); // [3, 3, 5, 5, 6, 7]
    }
}

复杂度

  • 时间 :每个元素最多入队/出队一次 → O(n)
  • 空间 :双端队列长度 ≤ k → O(k)

一句话记忆

"队头永远是当前窗口最大值,队尾单调递减踢小弟,过期下标及时扔 "------这就是滑动窗口最大值的 单调队列 套路。

相关推荐
疯狂打码的少年6 分钟前
【数据结构】交换类排序:冒泡与快速排序
数据结构·笔记·算法·排序算法
Nil20833 分钟前
leetcode 108有序数组转换为二叉搜索树
数据结构·算法·leetcode
高频因子挖掘机34 分钟前
QuantDash 成交量单位统一实战:从“手”到“股”的跨市场量化数据清洗全流程
后端·算法·github
Escalating_xu1 小时前
【C++ STL简介】从六大组件到容器、迭代器与算法协作
java·c++·算法
纪念 2292 小时前
算法二叉树(一)
算法
疯狂打码的少年2 小时前
【数据结构】哈希表:构造与冲突处理
数据结构·笔记·哈希算法·散列表
liulilittle2 小时前
llmx 学习手册 06 —— CPU 指令集优化(AVX-512 三层演进)
c++·学习·算法·ai·llm
土司大王3 小时前
LeetCode hot100——相交链表
算法·leetcode·链表
土司大王3 小时前
LeetCode hot100——回文链表
算法·leetcode·链表
淡海水3 小时前
03-02-线性-List-T-动态数组布局-扩容与操作成本
数据结构·windows·c#·list·编译·clr·机器码