剑指 Offer 59 - I. 滑动窗口的最大值
给定一个数组 nums 和滑动窗口的大小 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
提示:
你可以假设 k 总是有效的,在输入数组 不为空 的情况下,1 ≤ k ≤ nums.length。
注意:本题与主站 239 题相同:leetcode-cn.com/problems/sl…
解题思路:
代码实现:
单向队列:
class Solution:
def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
# 如果数组为空或者k=0,直接返回0
if not nums or not k:
return []
# 如果数组只有一个元素,直接返回该元素的值
if len(nums)==1:
return [nums[0]]
# 初始化队列和结果,队列存储数组下标
queue = []
res = []
for i in range (len(nums)):
# 如果当前队列最左侧存储的下标等于 i-k 的值,代表目前队列已满。
# 但是新元素需要进来,所以列表最左侧的下标出队列
if queue and queue[0] == i - k:
queue.pop(0)
# 对于新进的元素,如果队列里的元素都比它小,那么队列弹出所有元素
while queue and nums[queue[-1]] < nums[i]:
queue.pop()
# 新元素入队
queue.append(i)
# 将大元素加入结果数组
if i >= k - 1:
res.append(nums[queue[0]])
return res
双向队列:
class Solution:
def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
res = []
queue = collections.deque()
for i, num in enumerate(nums):
if queue and queue[0] == i - k:
queue.popleft()
while queue and nums[queue[-1]] < num:
queue.pop()
queue.append(i)
if i >= k - 1:
res.append(nums[queue[0]])
return res