Leetcode-滑動視窗的最大值_python
阿新 • • 發佈:2018-11-27
239.給定一個數組 nums,有一個大小為 k 的滑動視窗從陣列的最左側移動到陣列的最右側。你只可以看到在滑動視窗 k 內的數字。滑動視窗每次只向右移動一位。
返回滑動視窗最大值。
示例:
輸入: nums = [1,3,-1,-3,5,3,6,7], 和 k = 3
輸出: [3,3,5,5,6,7]
解釋:
滑動視窗的位置 最大值
[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
注意:
你可以假設 k 總是有效的,1 ≤ k ≤ 輸入陣列的大小,且輸入陣列不為空。
進階:
你能線上性時間複雜度內解決此題嗎?
思路:
1.根據優先佇列的概念,我們假設一個大頂堆,那麼一開始的[1,3,-1],這樣一排列成堆的樣子就是3在最上面,-1在左下角,1在右下角。。下一步就是[3,-1,-3]了,1就要被擠開了,擠開了也不影響什麼,-3再加進來就好了。總之我們需要做的是:(1)維護我們的Heap,也就是刪除離開視窗的元素,加入新的元素。這裡時間複雜度是logK (2)Max->Top,就是讓結果是堆頂的元素。複雜度是O(1),最後整體的複雜度是NLogK。有沒有更好的解法?
2.直接用佇列,而且是雙端佇列,也就是兩邊都能進能出的佇列。首先就是入佇列,每次滑動視窗都把最大值左邊小的數給殺死,也就是出隊,後面再滑動視窗進行維護,這樣相當於就是每一個數走過場,時間複雜度就是O(N*1),比思路1要小。
class Solution: def maxSlidingWindow(self, nums, k): """ :type nums: List[int] :type k: int :rtype: List[int] """ #嚴謹判斷輸入的數字是否合法 if not nums:return [] window, res = [], [] for i, x in enumerate(nums): if i>=k and window[0] <= i-k: #視窗滑動時的規律 window.pop(0) while window and nums[window[-1]] <= x: #把最大值左邊的數小的就清除。 window.pop() window.append(i) if i >= k-1: res.append(nums[window[0]]) return res