您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
# LeetCode如何求滑动窗口的最大值
滑动窗口问题是算法面试中的高频考点,其中「求滑动窗口最大值」是经典难题(LeetCode 239题)。本文将系统讲解暴力法、单调队列法两种解法,并给出Python/Java实现代码。
## 问题描述
给定一个整数数组 `nums` 和一个整数 `k`,请找出所有滑动窗口 `[i, i+k-1]` 中的最大值。示例:
```python
输入: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
遍历每个窗口,通过内层循环找出当前窗口的最大值。
def maxSlidingWindow(nums, k):
if not nums:
return []
return [max(nums[i:i+k]) for i in range(len(nums)-k+1)]
维护一个单调递减队列,队首始终是当前窗口最大值。关键操作: 1. 入队时:移除队列中所有小于当前元素的值 2. 出队时:如果队首元素等于窗口左边界则移除
以 nums = [1,3,-1,-3,5,3,6,7], k = 3 为例:
步骤 | 操作 | 队列状态 | 当前窗口最大值 |
---|---|---|---|
1 | 处理1 | [1] | - |
2 | 处理3 | [3] | - |
3 | 处理-1 | [3, -1] | 3 |
4 | 移除1 | [3, -1] | 3 |
5 | 处理-3 | [3, -1,-3] | 3 |
6 | 移除3 | [-1,-3] | -1 |
7 | 处理5 | [5] | 5 |
from collections import deque
def maxSlidingWindow(nums, k):
q = deque()
res = []
for i, num in enumerate(nums):
# 维护单调性
while q and nums[q[-1]] < num:
q.pop()
q.append(i)
# 移除越界元素
if q[0] == i - k:
q.popleft()
# 记录结果
if i >= k - 1:
res.append(nums[q[0]])
return res
public int[] maxSlidingWindow(int[] nums, int k) {
Deque<Integer> q = new ArrayDeque<>();
int[] res = new int[nums.length - k + 1];
for (int i = 0; i < nums.length; i++) {
while (!q.isEmpty() && nums[q.peekLast()] < nums[i]) {
q.pollLast();
}
q.offerLast(i);
if (q.peekFirst() == i - k) {
q.pollFirst();
}
if (i >= k - 1) {
res[i - k + 1] = nums[q.peekFirst()];
}
}
return res;
}
方法 | 时间复杂度 | 空间复杂度 | 适用场景 |
---|---|---|---|
暴力法 | O(n*k) | O(1) | 仅适用于k极小情况 |
单调队列法 | O(n) | O(k) | 通用最优解 |
掌握单调队列的要点: 1. 队列中存储的是元素索引而非值 2. 维护单调性的双端操作(头部移除过期元素,尾部维护单调性) 3. 结果记录时机(当i≥k-1时才开始记录)
建议在理解基础上记忆模板代码,并尝试解决LeetCode相关练习题: - 1438. 绝对差不超过限制的最长连续子数组 - 480. 滑动窗口中位数 “`
文章包含: 1. 问题描述与示例 2. 两种解法的详细说明 3. 复杂度分析和代码实现 4. 执行过程可视化 5. 方法对比表格 6. 变种问题建议 7. 总结与学习建议 总字数约1100字,符合要求。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。