leetcode -- Sliding Window Maximum -- 重点

来源:互联网 发布:985大学知乎 编辑:程序博客网 时间:2024/06/14 20:40

https://leetcode.com/problems/sliding-window-maximum/

思路见code,参考http://www.jianshu.com/p/7662caf4f39c
http://bookshadow.com/weblog/2015/07/18/leetcode-sliding-window-maximum/

为什么要用deque呢?

这里是滑动窗口,每次滑动,都会有值从右边进,然后又有值从左边出。所以用双向队列就很好。维护队头元素为当前窗口的最大值.因为向右滑动的时候,要从左边remove一个元素,如果这个元素是上一个window的最大值,那么就要更新这个最大值,这个新的最大值肯定出现在旧的最大值的后面,所以,这里用deque,队头为最大元素,下一个元素为这个最大元素后面的最大元素。。。

思路:

遍历数组nums,使用双端队列deque维护滑动窗口内有可能成为最大值元素的数组下标由于数组中的每一个元素至多只会入队、出队一次,因此均摊时间复杂度为O(n)记当前下标为i,则滑动窗口的有效下标范围为[i - (k - 1), i]若deque中的元素下标< i - (k - 1),则将其从队头弹出,deque中的元素按照下标递增顺序从队尾入队。这样就确保deque中的数组下标范围为[i - (k - 1), i],满足滑动窗口的要求。当下标i从队尾入队时,顺次弹出队列尾部不大于nums[i]的数组下标(这些被弹出的元素由于新元素的加入而变得没有意义)deque的队头元素即为当前滑动窗口的最大值

这里deque就是维护一个区间内第一大,第二大,。。。的结构,最大的放在队头

class Solution(object):    def maxSlidingWindow(self, nums, k):        """        :type nums: List[int]        :type k: int        :rtype: List[int]        """        res = []        d = collections.deque()        for i in range(len(nums)):            while d and d[-1] < nums[i]:#等于可以跳出了                d.pop()            d.append(nums[i])            if i > k - 1 and d[0] == nums[i - k]:            '''            这里i > k - 1,就是第一个windows已经建好了,开始滑动。d[0] == nums[i - k], 本来的windows index是从[i - (k-1), i],i现在往前走了一步,现在区间变成了[i-k, i],window长度为k+1, 要popleft掉第一个i-k元素。新的队头元素就是新的max            '''                d.popleft()            if i >= k - 1:#窗口开始滑动之后deque的第一个值就是结果。                res.append(d[0])        return res
0 0
原创粉丝点击