牛客网-Python-滑动窗口的最大值(双端队列)
题目描述
给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口,他们的最大值分别为{4,4,6,6,6,5}; 针对数组{2,3,4,2,6,2,5,1}的滑动窗口有以下6个: {[2,3,4],2,6,2,5,1}, {2,[3,4,2],6,2,5,1}, {2,3,[4,2,6],2,5,1}, {2,3,4,[2,6,2],5,1}, {2,3,4,2,[6,2,5],1}, {2,3,4,2,6,[2,5,1]}。
思路
对每次滑动窗口找到最大值,记录下最大值和最大值的下标。
若下标在窗口范围内,则比较新增加的值和当前最大值,若大于当前最大值则最大值和下标更改。
若下标不在窗口范围内,则再次遍历找最大值
代码
# -*- coding:utf-8 -*- class Solution: def maxInWindows(self, num, size): # write code here if size == 0: return [] resultList = [] result = num[0] flag = 0 for j in range(0,len(num)-size+1): if flag!=0 and flag>=j: if num[j+size-1]>=result: result = num[j+size-1] flag = j+size-1 else: result = num[j] flag = j for i in range(1,size): if result<=num[j+i]: result = num[j+i] flag = j+i resultList.append(result) return resultList
改进
用双端队列,列表的前端存放最大值的下标
窗口扩大时,做以下操作(删掉比它小的值和下标不在范围内的值,即可以保证对比了大小也可以保证顺序)
1.若末端值小于当前值,删除末端值
2.若当前下标在范围外,则删除
添加该元素
取以每次窗口最前端为下标的值
代码
# -*- coding:utf-8 -*- class Solution: def maxInWindows(self, num, size): # write code here result = [] res = [] for i in range(0,len(num)): flag = i-size+1 while(result and num[i]>=num[result[-1]]): del result[-1] while(result and result[0]<flag): del result[0] result.append(i) if flag>=0 and size>0: res.append(num[result[0]]) return res