Bootstrap

【刷题1】LeetCode 239. 滑动窗口最大值 java题解

题目

https://leetcode-cn.com/problems/sliding-window-maximum/
在这里插入图片描述

方法一:单调队列

https://blog.csdn.net/weixin_42970433/article/details/109174079

方法二:动态规划

分析

right[i] 是左侧块内的最大元素, left[j] 是右侧块内的最大元素。因此滑动窗口中的最大元素为 max(right[i], left[j])。
在这里插入图片描述

复杂度

时间复杂度:O(N),我们对长度为 N 的数组处理了 3次。
空间复杂度:O(N),用于存储长度为 N 的 left 和 right 数组,以及长度为 N - k + 1的输出数组。

代码

public int[] maxSlidingWindow(int[] nums, int k) {
    int len = nums.length;
    int[] maxLeft = new int[len];
    int[] maxRight = new int[len];
    //从左往右窗口的第一个最大值默认是数组第一个值
    maxLeft[0] = nums[0];
    //从右往左窗口的最后一个最大值是数组的最后一个值
    maxRight[len - 1] = nums[len - 1];

    for (int i = 1; i < len; i++) {
        //这里分别计算从前往后窗口的最大值和从后往前窗口的最大值。要搞懂这里的判断,如果
        //i % k == 0,表示到了下一个窗口
        maxLeft[i] = (i % k == 0) ? nums[i] : Math.max(maxLeft[i - 1], nums[i]);
        int j = len - i - 1;
        maxRight[j] = ((j + 1) % k == 0) ? nums[j] : Math.max(maxRight[j + 1], nums[j]);
    }
    //返回的结果值
    int[] res = new int[len - k + 1];
    for (int i = 0, j = 0; i < res.length; i++) {
        //取每个窗口内从左往右扫描的最后一个值和从右往左扫描的最后
        //一个值(如果从左边数是第一个)的最大值
        res[j++] = Math.max(maxRight[i], maxLeft[i + k - 1]);
    }
    return res;
}
class Solution {
  public int[] maxSlidingWindow(int[] nums, int k) {
    int n = nums.length;
    if (n * k == 0) return new int[0];
    if (k == 1) return nums;

    int [] left = new int[n];
    left[0] = nums[0];
    int [] right = new int[n];
    right[n - 1] = nums[n - 1];

    for (int i = 1; i < n; i++) {
        // from left to right
        //某一组的第一个
        if (i % k == 0) 
            left[i] = nums[i];  
        else 
            left[i] = Math.max(left[i - 1], nums[i]);

        // from right to left
        int j = n - i - 1;
        //j某一组的最后第一个
        if ((j + 1) % k == 0) 
            right[j] = nums[j];  // block_end
        else 
            right[j] = Math.max(right[j + 1], nums[j]);
    }

    int [] output = new int[n - k + 1];
    for (int i = 0; i < n - k + 1; i++)
      output[i] = Math.max(left[i + k - 1], right[i]);
    return output;
  }
}

结果

在这里插入图片描述

;