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

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

一句话记忆

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

相关推荐
2401_891482179 分钟前
C++代码复杂性分析
开发语言·c++·算法
keep intensify11 分钟前
单词搜索-
算法·深度优先
zx_zx_12311 分钟前
定长滑动窗口和不定长滑动窗口
数据结构·算法
mjhcsp18 分钟前
C++ 梯度下降法(Gradient Descent):数值优化的核心迭代算法
开发语言·c++·算法
yunyun3212325 分钟前
跨语言调用C++接口
开发语言·c++·算法
m0_5180194828 分钟前
C++中的装饰器模式变体
开发语言·c++·算法
xushichao198935 分钟前
高性能密码学库
开发语言·c++·算法
m0_5180194837 分钟前
C++代码混淆与保护
开发语言·c++·算法
m0_5698814740 分钟前
C++中的智能指针详解
开发语言·c++·算法
blackicexs43 分钟前
第九周第三天
算法