洛谷单调队列模板
n,k=map(int,input().split())
l=list(map(int,input().split()))
def sld(m,k):
max_r=[]
max_q=[]
min_r=[]
min_q=[]
for i,num in enumerate(m):
while max_q and m[max_q[-1]]<num:
max_q.pop()
max_q.append(i)
while min_q and m[min_q[-1]]>num:
min_q.pop()
min_q.append(i)
while max_q[0] <= i-k:max_q.pop(0)
while min_q[0] <=i-k:min_q.pop(0)
if i >=k-1:
max_r.append(m[max_q[0]])
min_r.append(m[min_q[0]])
return max_r,min_r
mx,mi=sld(l,k)
for i in mi:
print(i,end=" ")
print()
for j in mx:
print(j,end=" ")
蓝桥杯二维单调队列
def sliding_window(nums,k): #nums为一维数组,k为窗口大小
max_result=[] #用来记录每次的最大值
min_result=[] #用来记录每次的最小值
q_max=[] #记录一维数组中最大值的索引值
q_min=[] #记录一维数组中最小值的索引值
for i,num in enumerate(nums): #i表示索引值,num表示索引值对应的值
#维护最大值的单调递减队列
#最大值队列存在,且队列中右边元素小于当前值则删除队列右边元素
while q_max and nums[q_max[-1]]<num:
q_max.pop()
#将当前值添加到队列的右边
q_max.append(i)
#维护最小值的单调递增队列
#最小值队列存在,若队列最右边元素大于当前值则删除队列右边元素
while q_min and nums[q_min[-1]]>num:
q_min.pop()
#将当前值添加到队列的右边
q_min.append(i)
#移除窗口之外的索引值
#i-k表示当前索引值的前k个元素,表示窗口的最左端
#如果最大值/最小值的最左端位置与第一个索引值相同,则删除
if q_max[0]==i-k:q_max.pop(0)
if q_min[0]==i-k:q_min.pop(0)
#当窗口大小达到k时,则记录此时的最大值和最小值
if i>=k-1:
max_result.append(nums[q_max[0]])
min_result.append(nums[q_min[0]])
#返回最后的结果
return max_result,min_result
def sliding_windows(matrix, a, b): #matrix为二维数组,a×b为窗口大小
row_max = [] #用来记录每行最大值的二维矩阵
row_min = [] #用来记录每行最小值的二维矩阵
#对每行横移窗口,进行列压缩,将b列变为一列,只记录最值
for row in matrix:
max_list, min_list = sliding_window(row, b)
row_max.append(max_list) #将每行最大值列表入row_max
row_min.append(min_list) #将每行最小值列表入row_min
#对每列横移窗口,进行列压缩,将a列变为一列,只记录最值
sub_max = []
sub_min = []
for col in zip(*row_max): #通过zip函数得到其列列表
max_list, _ = sliding_window(col, a)
sub_max.append(max_list)
for col in zip(*row_min):
_, min_list = sliding_window(col, a)
sub_min.append(min_list)
#sub_max与sub_min即所有子矩阵的最大值和最小值矩阵
return sub_max,sub_min