239. Sliding Window Maximum
滑窗
题干:
Given an array nums, there is a sliding window of size k which is moving from the very left of the array to the very right. You can only see the k numbers in the window. Each time the sliding window moves right by one position. Return the max sliding window.
解释:
有一个大小为K的窗口,你只知道这个窗口里的数字,要求返回当前的最大值
思考:
暴力解很明显是要每次都把窗口内的值中最大的找出来。但是这样非常低效,原因在于每次滑动只变化两位数字,其他的数字之间的先后顺序其实是已经拍好了的,如果要重新排一次就很浪费时间。那么更深一层的想法是,既然是最大,那么我们就用一个最大堆,让他自动返回最大值不就好了。问题是最大栈中的数字位置是变化的,而且你无法高效的删除最大堆中某个非最大值。这个时候我们就要想到,每次滑动有哪些东西是已知的,首先上次窗口的最大值是已知的,这次要出窗的值是已知的,进窗口的也是已知的。那么什么时候最大值会变化,两种情况,首先是最大值恰好是出窗口的值,这种情况下应该选择之前排好序的第二大的数字;如果最大值没有出窗口,但是进来了一个更大的,那么之前的这个最大值还有必要记录吗?其实没有了,因为那个更大的数字肯定会在之前的最大值之后出窗口;总结一下就是,一旦有更大的数字进来,比新数字小的数字都没有保存的必要了。所以我们要用一个单调队列来实现。 时间效率88
答案:
from collections import deque
class Solution(object):
def maxSlidingWindow(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: List[int]
"""
if len(nums)==0:
return 0
q=deque()
res=[]
if k ==1:
return nums
q.append(nums[0])
for i in range(1,k):
tmp = nums[i]
while q and tmp > q[-1]:
q.pop()
q.append(tmp)
res.append(q[0])
for i in range(k,len(nums)):
j=i-k
left = nums[j]
right= nums[i]
if left == q[0]:
q.popleft()
while q and right>q[-1]:
q.pop()
q.append(right)
res.append(q[0])
return res