239. Sliding Window Maximum

给定一个数组和一个窗口大小K,要你从数组中按顺序将所有相邻的K个数中最大值输出。每一次窗口向右边移动一步。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# 
# 复杂度O(n)
class Solution(object):
def maxSlidingWindow(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: List[int]
"""
# 滑动窗口, 7 star, 面试遇到,当时想的是暴力的解法
# 维护一个双向队列,其保持递减顺序,若队列头位置不在窗口中,队列头出队列,
# 当前数小于队列尾或队列为空,则队列尾出队列,进行循环操作后,加入当前项。队列头即使当前窗口中的最大值。
if not nums:
return []
if len(nums) < k:
return [max(nums)]
queue = []
ret = []
# i代表当前遍历到的索引,窗口是以索引i为结尾到往前k项的,维护了一个队列,
# 队列保持递减顺序,这样每次队列中第一个元素就是当前窗口的最大值
for i in range(len(nums)):
# 队列不为空,但队列第一个元素小于等于i-k了,意味着它在窗口之外,需要丢弃
while queue and queue[0] <= i - k:
queue.pop(0)
# 从队列尾部开始,将所有小于当前项的去除
while queue and nums[queue[-1]] <= nums[i]:
queue.pop()
# 将当前索引入队列
queue.append(i)
# 大于等于k-1之后,每次都是取队列第一个元素,这个元素就是当前窗口最大值的索引
if i >= k - 1:
ret.append(nums[queue[0]])
return ret