Problem: 239. 滑动窗口最大值
@[TOC]
思路
这个问题可以使用一个数据结构叫做单调队列来解决。单调队列是一种特殊的队列,它可以在 O(1) 的时间复杂度内获取队列中的最大值(或最小值)。在这个问题中,我们可以从左到右遍历数组,将每个数字加入到单调队列中。同时,我们需要保持单调队列的第一个元素始终是当前窗口的最大值。
解题方法
我们首先初始化一个空的单调队列和一个结果数组。然后,我们从左到右遍历输入数组,对于每个元素,我们首先从单调队列的尾部开始,移除所有小于当前元素的元素,然后将当前元素加入到单调队列的尾部。这样,我们可以确保单调队列的第一个元素始终是当前窗口的最大值。 然后,我们需要检查单调队列的第一个元素是否在当前窗口的范围内,如果不在,我们就将其从单调队列中移除。最后,我们将单调队列的第一个元素加入到结果数组中。
复杂度
时间复杂度:
,其中n是数组的长度。每个元素只会被加入到单调队列一次,所以时间复杂度是线性的。
空间复杂度:
,在最坏的情况下,单调队列中可能会包含所有的元素,所以空间复杂度是线性的。
Code
class Solution {
public static int MAXN = 100001;
public static int[] deque = new int[MAXN];
public static int h, t;
public static int[] maxSlidingWindow(int[] nums, int k) {
h = t = 0;
int n = nums.length;
// 首先形成k - 1的窗口
for (int i = 0; i < k - 1; i++) {
while (h < t && nums[deque[t - 1]] <= nums[i]) {
t--;
}
deque[t++] = i;
}
int m = n - k + 1;
int[] ans = new int[m];
for (int l = 0, r = k - 1; l < m; l++, r++) {
while (h < t && nums[deque[t - 1]] <= nums[r]) {
t--;
}
deque[t++] = r;
ans[l] = nums[deque[h]];
if (deque[h] == l) {
h++;
}
}
return ans;
}
}