跳转链接
给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。
返回 滑动窗口中的最大值 。
示例1
输入: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
示例2
输入:nums = [1], k = 1
输出:[1]
1.总是输出每个滑动窗口内的最大值,则维护一个大小为k的大顶堆,
2.从第k位开始循环数组,若堆顶元素在窗口外,则弹出。否则加入res
class Solution(object):
def maxSlidingWindow(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: List[int]
"""
n = len(nums)
st = []
res = []
for i in range(k - 1):
heapq.heappush(st, (-nums[i], i))
for i in range(k - 1, n):
heapq.heappush(st, (-nums[i], i))
while st[0][1] < i - k + 1:
heapq.heappop(st)
res.append(-st[0][0])
return res
解法1: 思路一致
class Solution:
def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
n = len(nums)
# 注意 Python 默认的优先队列是小根堆
q = [(-nums[i], i) for i in range(k)]
heapq.heapify(q)
ans = [-q[0][0]]
for i in range(k, n):
heapq.heappush(q, (-nums[i], i))
while q[0][1] <= i - k:
heapq.heappop(q)
ans.append(-q[0][0])
return ans
作者:LeetCode-Solution
链接:https://leetcode.cn/problems/sliding-window-maximum/solution/hua-dong-chuang-kou-zui-da-zhi-by-leetco-ki6m/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
解法2:
用双向队列存储元素下标实现:
1.加入队列策略:
当元素小于队尾元素时,下标直接入队。否则,不断弹出队尾,直到队列为空或者队尾元素对应的值大于当前元素
2.从k遍历数组,先执行将当前元素入队的操作(1),此时若队首元素值小于窗口左边界,则不断弹出。
3.弹出队首加入res
1保证了队列中后面的下标一定大于前面的,队首的下标对应的元素值一定大于后面的。
class Solution:
def maxSlidingWindow(self, nums, k):
n = len(nums)
q = collections.deque()
for i in range(k):
while q and nums[i] >= nums[q[-1]]:
q.pop()
q.append(i)
ans = [nums[q[0]]]
for i in range(k, n):
while q and nums[i] >= nums[q[-1]]:
q.pop()
q.append(i)
while q[0] <= i - k:
q.popleft()
ans.append(nums[q[0]])
return ans