D10-读论文D10&算法D10复习(831kmp&154滑动窗口)

831 KMP

n = int(input())
p = ' '+ input()
m = int(input())
s = ' '+  input()

ne = [0]*100010
# 1、j从0开始,i从1开始
i,j = 1,0
# 2、到n+1
for i in range(2,n+1):
    while j and p[i]!=p[j+1]:
        j = ne[j]
    
    if p[i]==p[j+1]:
        j += 1
    ne[i] = j

j= 0
for i in range(1,m+1):
    while j and s[i]!=p[j+1]:
        j = ne[j]
    
    if s[i]==p[j+1]:
        j += 1
        # 3、当完全匹配后才打印
        if j==n:
            # 4、由于下标本身从0开始,我们处理(接收时从1开始),所以此处不加1
            print(i-j, end=' ')
            # 5、匹配完后进行下一项匹配,不用从头开始找,直接利用next匹配
            j = ne[j]

154滑动窗口

做的很糟糕,明天再做

1、后面的数会比前面的数呆的久,所以后面的数如果比前面的数更满足条件,则可将前面的数舍弃,形成单调队列。
2、要维持窗口大小,则在队列不为空的情况下,判断一下队头元素的值(下标)是否在当前窗口内(<i-k+1)
i=6,k=3 ====> 6,5,4 。 则判断q[hh]是否<4(i-k+1),如果小于4,则舍弃。
所以判断式子为if hh<=tt and q[hh]<i-k+1: hh+=1

n,k = map(int,input().split())
nums = list(map(int,input().split()))

q = [0]*1000010
hh,tt = 0,-1

for i in range(n):
    if hh<=tt and q[hh]<i-k+1:
        hh += 1
    while hh<=tt and nums[q[tt]]>= nums[i]:
        tt -= 1
    tt += 1
    q[tt] = i
    if i-k+1>=0:
        print(nums[q[hh]], end=' ')
print()

tt,hh = -1,0
q = [0]*1000010

for i in range(n):
    if hh<=tt and q[hh]<i-k+1:
        hh += 1
    while hh<=tt and nums[q[tt]]<= nums[i]:
        tt -= 1
    tt += 1
    q[tt] = i
    if i-k+1>=0:
        print(nums[q[hh]], end =' ')


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值