题目描述
给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。例如,如果输入数组{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]}。
思路
《剑指offer》P290
设置一个队列maxWindows
作为窗口,保存数字在array
中的下标,设滑动窗口大小为size
,滑动分为两个部分:
-
第一部分,先找到滑动串口范围内的第一个最大值。
遍历下标在0-size
之间的数,对于每一个数字array[i]
,先对maxWindows
中的数字从后往前与array[i]
比较,若array[i]
大,则将数从队列中pop()
。然后将
num[i]
压入滑动窗口。 -
第二部分,每次添加一个数,进行一次最大值输出。
对于每一个新进的值,先判断当前滑动窗口存的数值范围是否超过了size
范围(根据保存的index
差值判断),如果超过,则将滑动窗口头部的值pop()
。然后与第一部分同样的方法进行比较和压入。
code
# -*- coding:utf-8 -*-
class Solution:
def maxInWindows(self, num, size):
# write code here
maxWindows = []
res = []
# 边界判断
if size <= 0 or len(num) < size or not num:
return []
if size == 1:
return num
# 分两个部分放入数据
# 第一个部分是滑动窗口第一次填满
maxWindows.append(0)
for i in range(1, size):
# 从后往前判断当前数字是否比其他数字大
# 如果是,则删除已存的数字
while len(maxWindows) > 0 and num[maxWindows[len(maxWindows) - 1]] < num[i]:
maxWindows.pop()
maxWindows.append(i)
res.append(num[maxWindows[0]])
# 开始移动滑动窗口
for i in range(size, len(num)):
# 先判断当前窗口是否满了
while maxWindows[len(maxWindows) - 1] + 1 - maxWindows[0] >= size:
maxWindows.pop(0)
while len(maxWindows) > 0 and num[maxWindows[len(maxWindows) - 1]] < num[i]:
maxWindows.pop()
maxWindows.append(i)
res.append(num[maxWindows[0]])
return res