算法题:生成窗口最大值数组
最近在看左程云的《程序员代码面试指南》,感觉不错,题都分了类,很方便有目的的刷题,书里的代码都是java实现的,刚好最近在学习python,就用python去练习一下。
1. 问题描述
有一个整型数组arr和一个大小为w的窗口从数组最左边滑倒最右边,窗口每次向右边滑一个位置。
例如,数组值为[4,3,5,4,3,3,6,7],窗口大小为3时:
[4 3 5] 4 3 3 6 7 窗口中最大值为5
4 [3 5 4] 3 3 6 7 窗口中最大值为5
4 3 [5 4 3] 3 6 7 窗口中最大值为5
4 3 5 [4 3 3] 6 7 窗口中最大值为4
4 3 5 4 [3 3 6] 7 窗口中最大值为6
4 3 5 4 3 [3 6 7] 窗口中最大值为7
输入:整型数组arr, 窗口大小w。
输出:一个长度为n-w+1的数组res,res[i]表示每一种窗口状态下的最大值。
2.解决方法
定义一个双端队列qmax,将遍历的值递减的从后插入,队列首端的值便是最大值,每次判断更新队首的值是否过期,如果过期就弹出。
3.代码实现
# 首先定义一个队列,虽然直接用列表[]也可以。
class Queue(object):
def __init__(self):
self.list = []
def enqueue(self,item):
# 入队
#尾部进队,头部出队
self.list.append(item)
#头部进队,尾部出队
# self.list.insert(0,item)
def dequeue(self):
#出队
if self.is_empty():
print('队列空!')
return None
else:
return self.list.pop(0)
# return self.list.pop()
def peek(self):
if self.is_empty():
print('队列空!')
return None
else:
return self.list[len(self.list)-1]
def is_empty(self):
#判断是否为空,是空返回True,不空返回False
if self.list:
return False
else:
return True
def size(self):
#判断大小
return len(self.list)
# 功能函数
def getMaxWindow(arr, w):
#生成窗口最大数组值
#参数为一个数组arr,以及出口大小w
if len(arr)<w:
return None
qmax = Queue()
res = []
i = 0
while i<len(arr):
while not qmax.is_empty() and arr[qmax.peek()] < arr[i]:
qmax.list.pop()
qmax.enqueue(i)
if qmax.list[0] == i-w:
qmax.dequeue()
if i >= w - 1 :
res.append(arr[qmax.list[0]])
i += 1
return res
主函数:
if __name__ == "__main__":
# 最大窗口
a = [4, 3, 5, 4, 3, 3, 6, 7]
result = getMaxWindow(a, 3)
for item in result:
print('窗口最大值为{0}'.format(item))
运行结果:
窗口最大值为5
窗口最大值为5
窗口最大值为5
窗口最大值为4
窗口最大值为6
窗口最大值为7