D11-读论文D11&算法D11-835Trie树&复习(831kmp&154滑动窗口)

835 Trie字符串统计

1、son为二维数组,用来表示树结构
2、idx为节点编号
3、cnt为一维数组,标记是否有以某编号结尾的字符串
4、在插入操作中,如果son[p][u]不存在,就创建;然后p指向其。
]5、在查询操作中,如果没有则不存在;如果有,则继续指向。最后string走完了,看看最后一个点的idx在cnt中是否存在,即Trie树中是否有以这个点结尾的字符串。

# Trie树用来存储和查找字符串集合
N = 100010

n = int(input())
son = [[0]*26 for _ in range(N)]
idx, cnt = 0, [0]*N

def insert(string):
    global idx
    p = 0
    for i in range(len(string)):
        u = ord(string[i])-ord('a')
        if not son[p][u]:
            idx += 1
            son[p][u] = idx
        # 无论son[p][u]是否存在,即是否有这个孩子,p指针都指向这个孩子。没有就创建,有就直接指向
        p = son[p][u]
    # cnt记录是否有以idx为p的点结尾的字符串
    cnt[p] += 1
def query(string):
    global idx
    p = 0
    for i in range(len(string)):
        u = ord(string[i])-ord('a')
        if not son[p][u]:
            return 0
        p = son[p][u]
    return cnt[p]
for _ in range(n):
    op, pt = input().split()
    string = str(pt)
    if op=='I':
        insert(string)
    else:
        print(query(string))

KMP

KMP只能停留在记忆的阶段了哎哎

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

N = 100010
ne = [0]*N

j = 0
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
        if j==n:
            print(i-j, end=' ')
            j = ne[j]
            

滑动窗口

好绝望:不过这次思路理清了,只是细节做的很差
1、脑子里要时刻清楚q中装的是坐标,要放在nums中才是数字;同理,向q中记录的时候,放入的也是i而不是nums【i】
2、窗口的大小是由队列维护的,具体来说就是当前指针i到q【hh】的大小,每次要先判断窗口是不是超过k了
3、只有i指针指到比窗口长度大的时候,才开始打印,也就是i+1>=k的时候

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

# 找最小值时,队列是单调递增的
q = [0]*N
hh,tt = 0,-1
# 脑子里要有队列中装的是坐标啊,所以真正的数为nums[q[tt]]
for i in range(n):
    # 窗口大小是由目前的指针i和队头元素维护的
    if hh<=tt and i-q[hh]+1 >k:
        hh += 1
    while hh<=tt and nums[i]<=nums[q[tt]]:
        tt -= 1
    tt += 1
    q[tt] = i
    if i-k+1>=0:
        print(nums[q[hh]], end = ' ')
print()    
# 单调递减
q = [0]*N
hh,tt = 0,-1
for i in range(n):
    if hh<=tt and i-q[hh]+1>k:
        hh += 1
    while hh<=tt and nums[i]>=nums[q[tt]]:
        tt -= 1
    tt += 1
    q[tt] = i
    if i-k+1>=0:
        print(nums[q[hh]], end= ' ')
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值