滑动窗口最大值
理解题目:
题目要求在给定整数数组 nums 和滑动窗口的大小 k 的情况下,找到滑动窗口中的最大值。
代码实现:
import java.util.ArrayDeque;
import java.util.Deque;
public class SlidingWindowMaximum {
// 滑动窗口最大值
public int[] maxSlidingWindow(int[] nums, int k) {
if (nums == null || nums.length == 0 || k <= 0) {
return new int[0];
}
int n = nums.length;
int[] result = new int[n - k + 1];
int index = 0;
Deque<Integer> deque = new ArrayDeque<>();
for (int i = 0; i < n; i++) {
// 移除窗口左边界外的元素
while (!deque.isEmpty() && deque.peek() < i - k + 1) {
deque.poll();
}
// 移除队列中比当前元素小的元素,保证队首元素是当前窗口的最大值
while (!deque.isEmpty() && nums[i] >= nums[deque.peekLast()]) {
deque.pollLast();
}
deque.offer(i); // 将当前索引加入队列
// 添加窗口最大值到结果数组
if (i >= k - 1) {
result[index++] = nums[deque.peek()];
}
}
return result;
}
}
步骤解释:
1. 首先检查数组是否为空,滑动窗口大小是否有效,如果无效则返回空数组。
2. 创建一个结果数组 result
用于存储每个滑动窗口的最大值,初始化结果数组的索引 index
为0。
3. 创建一个双端队列 deque
,用于存储当前窗口中的元素索引。
4. 遍历整个数组 nums
,对于每个元素:
- 移除双端队列中窗口左边界外的元素,即索引小于当前窗口左边界的元素。
- 移除队列中比当前元素小的元素,保证队首元素是当前窗口的最大值。
- 将当前索引加入队列。
- 如果当前索引大于等于窗口大小 k - 1,说明窗口形成完毕,将窗口最大值加入结果数组中。
5. 返回结果数组 result
。
时间复杂度:遍历数组一次,时间复杂度为 O(n)。
空间复杂度:双端队列 deque
最坏情况下需要存储窗口大小的元素,空间复杂度为 O(k)。