滑动窗口最大值

50 阅读1分钟

给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。

返回滑动窗口中的最大值。

思路:

  • 使用双头队列,使得队列保持单调递减;
  • 如果当前遍历到的数比队尾小,加入队尾;
  • 如果当前遍历到的数比队尾大,队尾出列;
  • 重复上一步,直到找到更大的队尾。

注意事项:

  • 队列中存储的是nums的位置,而不是nums的值,否则,窗口能看到的位置很难维护;
  • 如果单调队列中存储的是nums的位置,只需使用i(当前遍历到的数的位置)-deque[0](目前最大的数的位置)>=k,来判断队头是否需要出列即可。
class Solution(object):
    def maxSlidingWindow(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: List[int]
        """
        if len(nums) == 1 or len(nums) == 0 or k==1:
            return nums
        deque = collections.deque()
        result = list()
        #注意,队列存储下标
        for i in range(len(nums)):
            #保证第一个元素能进入队列
            if len(deque)==0:
                deque.append(i)
                continue
            #判断队列能看到的地方
            if (i - deque[0]) >= k:
                deque.popleft()
            #判断当前数
            #加速版
            #直接判断是否是最大值
            # if nums[i] >= nums[deque[0]]:
            #     deque.clear()
            #     deque.append(i)
            #如果不是最大值的情况
            # else:
            #     while nums[i] >= nums[deque[-1]]:
            #         deque.pop()
            #两种情况
            while len(deque)!=0 and nums[i] >= nums[deque[-1]]:
                deque.pop()
            deque.append(i)
            #到了一定位置后再加入结果
            if i >= k-1 :
               result.append(nums[deque[0]])
        return result