Files
LeetCode/子串/2. 滑动窗口最大值.md
T
2025-09-30 10:47:20 +08:00

90 lines
2.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 滑动窗口最大值
## 题目
给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。
返回 滑动窗口中的最大值 。
示例 1:
输入:nums = [1,3,-1,-3,5,3,6,7], k = 3
输出:[3,3,5,5,6,7]
解释:
滑动窗口的位置 最大值
--------------- -----
[1 3 -1] -3 5 3 6 7 3
1 [3 -1 -3] 5 3 6 7 3
1 3 [-1 -3 5] 3 6 7 5
1 3 -1 [-3 5 3] 6 7 5
1 3 -1 -3 [5 3 6] 7 6
1 3 -1 -3 5 [3 6 7] 7
示例 2:
输入:nums = [1], k = 1
输出:[1]
提示:
1 <= nums.length <= 105
-104 <= nums[i] <= 104
1 <= k <= nums.length
## 思路
- 关键点
- 如果进入窗口的比窗口内的元素大,那么窗口内小于该元素的一定不会是最大值
- 双端队列(单调递减)
- 出队
- 窗口移动,淘汰最左元素(需要判定)
- 淘汰小于新数的右侧元素
- 入队
- 新元素入队
## 代码
```java
class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
// Init: deque, res[]
Deque<Integer> deque = new LinkedList<>();
int[] res = new int[nums.length - k + 1];
// Traverse: Before
for (int i = 0; i < k; i++) {
// In
int cur = nums[i];
// Out
while (!deque.isEmpty() && deque.peekLast() < cur) {
deque.removeLast();
}
deque.addLast(cur);
}
// Res
res[0] = deque.peekFirst();
// Traverse: After
for (int i = k; i < nums.length; i++) {
// In
int cur = nums[i];
// Out 1
if(!deque.isEmpty() && deque.peekFirst() == nums[i - k]) {
deque.removeFirst();
}
// Out 2
while (!deque.isEmpty() && deque.peekLast() < cur) {
deque.removeLast();
}
deque.addLast(cur);
// Res
res[i - k + 1] = deque.peekFirst();
}
return res;
}
}
```