1.题目
滑动窗口的最大值
2.描述
给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。例如,如果输入数组{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]}。
3.解题思路
1.滑动窗口和最大值应当是队列。
2.先根据读取的滑动窗口大小,找出指定数组中的各个滑动窗口内的数据。然后返回其中数据的最大值。
3.考虑窗口大小的边界值,即size为0的情况。
python实现
- 两个数组辅助空间(window-2D、maxium-1D)
class Solution:
def maxInWindows(self, num, size):
window = []
maxium = []
if size==0:
return []
for i in range(len(num)-size+1):
window.append([])
for j in (num[i : i+size]):
window[i].append(j)
maxium.append(max(window[i]))
return(maxium)
先把每个窗口的数据存入window,然后求每个窗口的最大值。可追溯每个滑动窗口的数据及对应的最大值。
- 两个数组辅助空间(window-1D、maxium-1D)
class Solution:
def maxInWindows(self, num, size):
maxium = []
if size == 0:
return []
for i in range(len(num)-size+1):
window = []
for j in (num[i : i+size]):
window.append(j)
maxium.append(max(window))
return(maxium)
每更新一次窗口清一次window,可追溯最后一个窗口数据和每个滑动窗口的最大值。
- 一个数组辅助空间(maxium-1D)
class Solution:
def maxInWindows(self, num, size):
maxium = []
if size == 0:
return []
for i in range(len(num)-size+1):
maxium.append(max(num[i:i+size]))
return(maxium)
不可追溯所有窗口数据,只可追溯最大值,但从基本功能实现的角度是最节省内存空间的方法。
- 使用栈的push、pop、empty、top四种操作实现队列操作,基于冒泡排序求队列最大值。
class Stack:
def __init__(self):
self.stack = []
self.maxstack = [] #最大值栈
def push(self, x):
self.stack.append(x) #栈空或x大于栈顶
if not self.maxstack or self.maxstack[-1] <= x:
self.maxstack.append(x) #入最大值栈
def pop(self):
topone = self.stack.pop() #出栈元素等于最大值栈顶元素
if topone == self.maxstack[-1]:
self.maxstack.pop() #出最大值栈
def empty(self):
return not self.stack #判断栈空
def top(self):
return self.stack[-1] #取栈顶
def max(self):
return self.maxstack[-1] #取最大值栈顶
class Queue:
def __init__(self):
self.stack1 = Stack() #作入列
self.stack2 = Stack() #将stack1倒序后作出列
def enqueue(self, x): #入列
self.stack1.push(x)
def dequeue(self): #出列
if self.stack2.empty():
while not self.stack1.empty(): #直到stack1出栈到空
one = self.stack1.top() #stack1取栈顶
self.stack1.pop() #stack1当前栈顶出栈
self.stack2.push(one) #stack1当前栈顶,入栈到stack2
#ret = self.stack2.top()
self.stack2.pop() #stack2出栈
def getmax(self):
tmax = 0
if not self.stack1.empty(): #入队列状态时
tmax = self.stack1.max()
if not self.stack2.empty(): #出队列状态时
tmax = max(self.stack2.max(), tmax)
return tmax
class Solution:
def maxInWindows(num, size):
queue = Queue()
maxlist = []
if len(num) < size or size == 0:
return maxlist
for i in range(size):
queue.enqueue(num[i])
maxlist.append(queue.getmax())
for i in range(size, len(num)):
queue.dequeue()
queue.enqueue(num[i])
maxlist.append(queue.getmax())
return maxlist
用两个栈实现入队列和出队列操作,利用冒泡排序求目标栈的最大值,并存入最大值栈,如果目标栈出栈元素等于最大值栈顶,则将最大值栈顶元素出栈。