每日一题:剑指 Offer 59 - I. 滑动窗口的最大值

每日一题:剑指 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%的用户
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值