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

用 双端队列(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)

一句话记忆

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

相关推荐
动词ing15 分钟前
【题目练习】外观数列
算法
余额瞒着我当琳16 分钟前
C++11,发展历史浅谈,初始化列表和对象初始化,右值引用和移动语义
java·开发语言·c++·算法
suhan29 分钟前
【数据结构】六、图:4.图的遍历(深度优先算法DFS、广度优先算法BFS)
数据结构·算法·排序算法
suhan29 分钟前
【数据结构】六、图:3.十字链表、邻接多重表、边集数组
数据结构·算法·排序算法
Dola_Zou33 分钟前
工商业储能系统核心策略
算法·自动化·软件工程
Tsuki_tl34 分钟前
【优选算法:双指针】——复写零题解
java·c++·算法·leetcode·数组·双指针·复写零
Rain的Java大神之路1 小时前
面了上百人,我最爱问的LeetCode 1「两数之和」:能背代码的很多,能讲清“先查后存”的没几个
java·后端·算法
Ivanqhz1 小时前
超参数考量与设计
数据库·人工智能·深度学习·算法·机器学习
雪落漂泊1 小时前
C++算法 滑动窗口篇(上)
开发语言·c++·算法
吞下星星的少年·-·1 小时前
Div.2 CF edu195A题(数学,贪心)
数学·算法·贪心