洛谷单调队列模板
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_resultdef 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_maxrow_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