单调队列与二维单调队列

洛谷单调队列模板

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
posted @ 2025-04-01 20:51  邓佑孤  阅读(9)  评论(0)    收藏  举报