LeetCode 239. 滑动窗口最大值

LeetCode 239. 滑动窗口最大值

跳转链接

  • 题目描述:

给你一个整数数组 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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值