题目描述:
给定一个数组 nums
,有一个大小为 k
的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k
个数字。滑动窗口每次只向右移动一位。
返回滑动窗口中的最大值。
示例:
输入: 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
解题思路:
可以使用双端队列(deque)来解决这个问题。双端队列可以在两端进行插入和删除操作,非常适合维护一个滑动窗口内的最大值。
具体步骤:
- 初始化一个双端队列和一个结果数组。
- 遍历数组
nums
:- 对于每个元素,从队列的尾部开始,移除所有小于当前元素的值,因为这些值不可能成为后续窗口的最大值。
- 将当前元素的索引添加到队列的尾部。
- 如果队列的头部元素(即最大值的索引)已经不在当前窗口内(即索引小于窗口的左边界),将其移除。
- 当窗口形成后(即遍历的元素数大于等于
k
),将队列头部的元素(即当前窗口的最大值)添加到结果数组中。
- 返回结果数组。
代码实现:
from collections import deque
def maxSlidingWindow(nums, k): if not nums or k <= 0: return []
result = []
deque = deque()
for i in range(len(nums)):
# 移除所有小于当前元素的值
while deque and nums[deque[-1]] < nums[i]:
deque.pop()
# 添加当前元素的索引
deque.append(i)
# 移除不在窗口内的元素
if deque[0] < i - k + 1:
deque.popleft()
# 窗口形成后,添加最大值到结果数组
if i >= k - 1:
result.append(nums[deque[0]])
return result
示例
nums = [1, 3, -1, -3, 5, 3, 6, 7] k = 3 print(maxSlidingWindow(nums, k)) # 输出: [3, 3, 5, 5, 6, 7]
复杂度分析:
- 时间复杂度:O(n),每个元素最多被添加和移除一次。
- 空间复杂度:O(k),双端队列最多存储
k
个元素的索引。
这种方法利用了双端队列的特性,高效地解决了滑动窗口最大值的问题。希望这个解答对你有帮助!如果有更多问题,欢迎继续提问。
发表回复