窗口最大值更新结构

窗口内最大值的更新结构
#双端队列,双向链表结构,从头到尾从大到小
#加数:没有直接进;小于原来,直接进;大于原来,弹出数,直到找到该数的位置,进入
#减数:看头部下标是否过期,出窗口,没过期,不动
#窗口最大值即为头部最大值

from collections import deque
def maxwindow(nums,k):
    if k==1:
        return nums
    qq=deque([])#创建队列
    qq.append(0)#将0加入
    res=[]
    for x,y in enumerate(nums[1:],1): #x,y存储当前元素的下标和nums值,从位置1开始
        if nums[qq[-1]]<=y: #如果当前数比队尾元素大,弹出
            for i in range(len(qq)-1,-1,-1):
                if nums[qq[i]]>y:
                    break
                else:
                    qq.pop()
        qq.append(x) #加入当前数
        if qq[0]<=x-k:   #若队头元素过期,弹出队头元素
            qq.popleft()
        if x>=k-1: #若是一个完整窗口,更新结果列表res
            res.append(nums[qq[0]])
    return res
   
arr=[1,2,4,2,6,2]
print(maxwindow(arr,3))

另一种写法:
队列中只存下标

from collections import deque
def maxwindow(nums,w):  #w为窗口大小
    queue=deque()
    res=[]
    for i in range(len(nums)):
        while queue and nums[queue[-1]]<=nums[i]:
            queue.pop()
        queue.append(i)
        if queue[0]==i-w:    #过期,弹出
            queue.popleft()
        if i>=w-1:
            print(queue)
            res.append(nums[queue[0]])
    return res
nums=[1,2,3,8,4,2,6,7]
print(maxwindow(nums,3))

应用:
最大值-最小值<num的子数组数量
窗口最大值、最小值更新结构

l-r若满足条件,往里缩肯定满足条件,往外扩肯定不满足条件
从0开始找到每个位置满足条件的子数组数量
在这里插入图片描述


from  collections import deque
def alllessnum(arr,num):
    qmin=deque()
    qmax=deque()
    l=0
    r=0
    res=0
    while l<len(arr):
        while r<len(arr):
            while qmin and arr[qmin[-1]]>=arr[r]:  #最小值更新结构
                qmin.pop()
            qmin.append(r)
            while qmax and arr[qmax[-1]]<=arr[r]:  #最大值更新结构
                qmax.pop()
            qmax.append(r)
            if arr[qmax[0]]-arr[qmin[0]]>num:  #扩到不达标的位置
                break
            r+=1
        if qmin[0]==l:                           #判断过不过期
            qmin.popleft()
        if qmax[0]==l:                           #判断过不过期
            qmax.popleft()
            
        res+=r-l       #每个位置满足条件的子数组个数
        l+=1
    return  res
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值