Sliding Window Maximum
题目描述
For example,
Given nums = [1,3,-1,-3,5,3,6,7], and k = 3.
Window position Max
--------------- -----
[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
Therefore, return the max sliding window as [3,3,5,5,6,7].
Follow up:
Could you solve it in linear time?
解题方法
方法1
最直观的方法是维护一个heap, sliding window用类似2 pointer的方法做,
然后heap可以每次快速找到max, 但是heap的插入删除操作都需要O(logn)
方法2
用一个head和tail都可以快速插入/删除的数据结构,我们可以想到deque.
而deque没有办法快速求max,那怎么办呢?我们想取得最大值的时间为
o(1), 并且可以快速delete,根据类似min stack的做法。我们在deque里只放
可以成为max的候选value,并且只在头部删去这个值的时候将它从deque中pop
出去。
那么在遇到比当前deque head大的value时,我们就应该head pop出去直到
head >= current value.
注意点
- 将新value加入deque的时候,是将tail部分比它小的值都pop出去
- 删除head的value时,是从popleft()
Solution
from collections import deque
class Solution(object):
def maxSlidingWindow(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: List[int]
"""
if not nums:
return []
length = len(nums)
result = []
dq = deque()
for i in range(length):
# 将新的value加入到deque
while dq and dq[-1] < nums[i]:
dq.pop()
dq.append(nums[i])
# 如果多于k个element了,就要将头部的pop出去(如果nums[i-k]的value是头部的话)
if i >= k and nums[i-k] == dq[0]:
dq.popleft()
# 将当前最大值加入结果
if i >= k - 1:
result.append(dq[0])
return result