滑窗里的Maximum 与LeetCode携手掌握滑动窗口算法
2024-02-14 08:29:43
LeetCode 239 滑动窗口最大值
LeetCode 239. 滑动窗口最大值是一个经典的算法题目,也是面试中的高频题。题目如下:
给定一个整数数组 nums 和一个整数 k,请找到一个大小为 k 的滑动窗口,使得窗口中的最大值最大。滑动窗口每次只能向右移动一位。
例如,对于数组 nums = [1, 3, -1, -3, 5, 3, 6, 7] 和 k = 3,滑动窗口的最大值分别是 [3, 3, 5, 5, 6, 7]。
滑动窗口算法
滑动窗口算法是一种解决连续子数组问题的一种有效方法。它的基本思想是:使用一个窗口在数组中滑动,每次滑动一步,并计算窗口中的最大值。当窗口滑到数组的末尾时,算法就结束了。
在 LeetCode 239. 滑动窗口最大值 这道题中,我们可以使用队列来实现滑动窗口。队列是一种先进先出(FIFO)的数据结构,它允许我们在窗口中快速地添加和删除元素。
具体来说,我们可以使用一个双端队列(Deque)来实现滑动窗口。双端队列是一种特殊的队列,它允许我们在队列的头部和尾部添加和删除元素。这样,当窗口滑到数组的末尾时,我们可以快速地删除队列中的第一个元素,并添加新的元素到队列的末尾。
代码实现
from collections import deque
def max_sliding_window(nums, k):
"""
计算数组 nums 中大小为 k 的滑动窗口的最大值。
参数:
nums: 一个整数数组。
k: 滑动窗口的大小。
返回:
一个列表,其中包含滑动窗口中的最大值。
"""
# 检查输入是否合法。
if k <= 0 or k > len(nums):
raise ValueError("Invalid value of k.")
# 创建一个双端队列来存储窗口中的元素。
window = deque()
# 在窗口中添加前 k 个元素。
for i in range(k):
while window and nums[i] > window[-1]:
window.pop()
window.append(nums[i])
# 计算滑动窗口中的最大值。
max_values = [window[0]]
# 遍历数组中的剩余元素。
for i in range(k, len(nums)):
# 从窗口中删除第一个元素。
if window[0] == nums[i - k]:
window.popleft()
# 在窗口中添加新的元素。
while window and nums[i] > window[-1]:
window.pop()
window.append(nums[i])
# 计算滑动窗口中的最大值。
max_values.append(window[0])
# 返回滑动窗口中的最大值。
return max_values
时间复杂度和空间复杂度
滑动窗口算法的时间复杂度是 O(n),其中 n 是数组 nums 的长度。这是因为算法需要遍历数组中的每个元素,并在每次遍历时对窗口进行更新。
滑动窗口算法的空间复杂度是 O(k),其中 k 是滑动窗口的大小。这是因为算法需要使用一个队列来存储窗口中的元素,而队列的大小最多为 k。
总结
滑动窗口算法是一种解决连续子数组问题的一种有效方法。它可以用于解决各种各样的问题,例如 LeetCode 239. 滑动窗口最大值。滑动窗口算法的时间复杂度是 O(n),空间复杂度是 O(k)。