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= ' ')