每日一题:剑指 Offer 59 - I. 滑动窗口的最大值
一、题目
给定一个数组 nums 和滑动窗口的大小 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 ≤ 输入数组的大小。
2、方法
(1)暴力遍历时间复杂度 O ( n k ) O(nk) O(nk)
(2)单调双端队列 O ( n ) O(n) O(n):每个元素最多在单调队列中push和pop一次。
class Solution:
def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
### 1、暴力法
# length = len(nums)
# if length==0:
# return []
# result = []
# for start in range(0, length-k+1):
# end = start + k
# maxValue = nums[start]
# for i in range(start, end):
# if nums[i] > maxValue:
# maxValue = nums[i]
# result.append(maxValue)
# return result
### 2、单调队列
from collections import deque
### 单调双端队列:从队首到队尾单调递减
class MonotonousDeque(object):
def __init__(self):
self.deque = deque()
def push(self, value):
# 注意value>self.deque[-1],不要加等号,相等的数值也要放进去,看popValue逻辑
while len(self.deque)>0 and value>self.deque[-1]:
self.deque.pop()
self.deque.append(value)
def getMax(self):
return self.deque[0]
def popValue(self, popV):
if self.deque[0]==popV:
self.deque.popleft()
length = len(nums)
if length==0:
return []
result = []
windows = MonotonousDeque()
for i in range(length):
if i<k-1:
windows.push(nums[i])
else:
# print(windows.deque)
windows.push(nums[i])
value = windows.getMax()
result.append(value)
windows.popValue(nums[i-k+1]) # 窗口最左侧的元素是否等于当前最大值
return result
执行用时:96 ms, 在所有 Python3 提交中击败了46.15%的用户
内存消耗:18.3 MB, 在所有 Python3 提交中击败了7.20%的用户