返回轨道
算法 · 2026-05-14 · 22 阅读

P93 滑动窗口中的最大值

算法 22 阅读

信号摘要

难度:Hard · 时长:10:10 · leetcode 239 · lintcode 362

P93 滑动窗口中的最大值

未对外公开播放权限
点击查看说明

描述

这个题目说的是,给你一个整数数组和整数 k,k 表示滑动窗口的大小,滑动窗口从左向右滑过数组,每移动一个位置,你要计算出当前滑动窗口内 k 个数字的最大值。最后返回这个最大值数组。

比如说,给你的数组是 0, 4, 2, 1, 0, 8, 2,给你的滑动窗口大小 k 等于 3。我们使用大小为 3 的滑动窗口,来找到这个最大值序列。
  • 第一个滑动窗口内的数字是 0, 4, 2,最大值为 4
  • 移动窗口,窗口内数字变为 4, 2, 1,最大值仍然为 4
  • 继续移动窗口,窗口内数字变为 2, 1, 0,最大值变为 2
  • 接着移动窗口,窗口内数字变为 1, 0, 8,最大值变为 8
  • 继续移动窗口,最后窗口内的数字变为 0, 8, 2,最大值仍然是 8

这时滑动窗口再移动的话,窗口内的数字就不足 k 个,于是结束处理过程。最后就得到了最大值数组 4, 4, 2, 8, 8。

代码

public class AlgoCasts {

  // Time: O(k*n), Space: O(1)
  public int[] maxNumInSlidingWindowBruteForce(int[] nums, int k) {
    if (nums == null || nums.length == 0) return nums;
    int n = nums.length;
    int[] result = new int[n - k + 1];
    for (int left = 0; left <= n-k; ++left) {
      int max = nums[left];
      for (int i = left; i < left+k; ++i) {
        max = Math.max(max, nums[i]);
      }
      result[left] = max;
    }
    return result;
  }

  // Time: O(n*log(k)), Space: O(k)
  public int[] maxNumInSlidingWindowTreeMap(int[] nums, int k) {
    if (nums == null || nums.length == 0) return nums;
    int n = nums.length, p = 0;
    TreeMap<Integer, Integer> map = new TreeMap<>();
    for (int i = 0; i < k; ++i) map.put(nums[i], i);
    int[] result = new int[n - k + 1];
    result[p++] = map.lastKey();
    for (int i = k; i < n; ++i) {
      if (map.get(nums[i-k]) == i-k) map.remove(nums[i-k]);
      map.put(nums[i], i);
      result[p++] = map.lastKey();
    }
    return result;
  }

  // Time: O(n), Space: O(n)
  public int[] maxNumInSlidingWindowOn(int[] nums, int k) {
    if (nums == null || nums.length == 0) return nums;
    int n = nums.length;
    int[] result = new int[n - k + 1];
    int[] maxFromLeft = new int[n];
    int[] maxFromRight = new int[n];
    maxFromLeft[0] = nums[0];
    maxFromRight[n-1] = nums[n-1];
    for (int i = 1, j = n-2; i < n; ++i, --j) {
      maxFromLeft[i] = i % k == 0 ? nums[i] : Math.max(maxFromLeft[i-1], nums[i]);
      maxFromRight[j] = j % k == k-1 ? nums[j] : Math.max(maxFromRight[j+1], nums[j]);
    }
    for (int i = 0; i <= n-k; ++i) {
      result[i] = Math.max(maxFromRight[i], maxFromLeft[i+k-1]);
    }
    return result;
  }

}

📡 通讯频道