代码改变世界

[LeetCode] 239. Sliding Window Maximum_Hard tag: deque

2019-06-26 11:03  Johnson_强生仔仔  阅读(189)  评论(0编辑  收藏  举报

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.

Example:

Input: nums = [1,3,-1,-3,5,3,6,7], and k = 3
Output: [3,3,5,5,6,7] 
Explanation: 

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

Note: 
You may assume k is always valid, 1 ≤ k ≤ input array's size for non-empty array.

Follow up:
Could you solve it in linear time?

这个题目如果直接用一个for loop,然后排序的话是n * k 的时间复杂度,如果用O(n) 的时间复杂度的话,考虑3种数据结构, stack,queue 和deque,这个题目实际上是可以用一个递减stack来实现,每次取stack[0], 只不过有个问题是如果stack[0]已经不在window里面了,那么需要pop出stack[0], 时间复杂度会是O(k), 所以要用deque来实现。

Code:

T: O(n * k)

class Solution:
    def slidMax(self, nums):
        ans, n = [], len(nums)
        for i in range(0, n - k + 1):
            ans.append(max(nums[i:i + k]))
        return ans

 

T: O(n)

import collections
class Solution:
    def slidMax(self, nums):
        queue, ans = collections.deque(), []
        for i, num in enumerate(nums):
            while queue and queue[-1][1] < num:
                queue.pop()
            queue.append((i, num))
            if queue[0][0] < i - k  + 1:
                 queue.leftpop()
            if i >= k - 1:
                ans.append(queue[0][1])
        return ans