算法笔记(二)——数据结构(Python实现) 数据结构 单链表 N = int(1e5+10) e=[0]*N ne=[0]*N head=-1 idx=1 def insert(x): global idx, head e[idx]=x ne[idx]=head head=idx idx+=1 def add(k, x): global idx e[idx]=x ne[idx]=ne[k] ne[k]=idx idx+=1 def remove(k): global idx, head if k==0: head = ne[head] else: ne[k]=ne[ne[k]] n = int(input()) for _ in range(n): s = input().split() op=s[0] if op=='H': insert(int(s[1])) elif op=='I': add(int(s[1]), int(s[2])) else: remove(int(s[1])) i=head while i!=-1: print(e[i], end=' ') i=ne[i] 双链表 N = int(1e5+10) e=[0]*N l=[0]*N r=[0]*N idx=0 def init(): global idx r[2]=1 l[1]=2 idx=3 def insert(k, x): global idx e[idx]=x l[idx]=k r[idx]=r[k] l[r[k]]=idx r[k]=idx idx+=1 def remove(k): l[r[k]]=l[k] r[l[k]]=r[k] init() m=int(input()) for _ in range(m): s=input().split() if s[0]=='L': x=int(s[1]) insert(2,x) elif s[0]=='R': x=int(s[1]) insert(l[1],x) elif s[0]=='D': k=int(s[1])+2 remove(k) elif s[0]=='IL': k=int(s[1])+2 x=int(s[2]) insert(l[k],x) elif s[0]=='IR': k=int(s[1])+2 x=int(s[2]) insert(k,x) i=2 while i!=0: if i==2 or i==1: i=r[i] continue print(e[i],end=" ") i=r[i] 栈 N = int(1e5+10) # 假设N的值为100 stk = [0] * N tt = 0 # 向栈顶插入一个数 tt += 1 stk[tt] = x # 从栈顶弹出一个数 tt -= 1 # 栈顶的值 stk[tt] # 判断栈是否为空 if tt > 0: pass 队列 N = 100 # 假设N的值为100 q = [0] * N hh = 0 tt = -1 # 向队尾插入一个数 tt += 1 q[tt] = x # 从队头弹出一个数 hh += 1 # 队头的值 q[hh] # 判断队列是否为空 if hh <= tt: pass N = 100 # 假设N的值为100 q = [0] * N hh = 0 tt = 0 # 向队尾插入一个数 q[tt] = x tt += 1 if tt == N: tt = 0 # 从队头弹出一个数 hh += 1 if hh == N: hh = 0 # 队头的值 q[hh] # 判断队列是否为空 if hh != tt: pass 单调栈 tt = 0 stk = [0] * (n + 1) for i in range(1, n + 1): while tt and check(stk[tt], i): tt -= 1 stk[tt + 1] = i tt += 1 单调队列 n = 10 # 假设n的值为10 hh = 0 tt = -1 q = [0] * n for i in range(n): while hh <= tt and check_out(q[hh]): hh += 1 while hh <= tt and check(q[tt], i): tt -= 1 q[tt + 1] = i tt += 1 N = int(1e6+10) q=[0 for _ in range(N)] n,k=map(int, input().split()) a=[0]+[int(x) for x in input().split()] hh,tt=0,-1 for i in range(1,n+1): if hh<=tt and i-q[hh]+1>k: hh+=1 while hh<=tt and a[q[tt]] >= a[i]: tt-=1 tt+=1 q[tt]=i if i >= k: print(a[q[hh]], end=" ") print() hh,tt=0,-1 for i in range(1,n+1): if hh<=tt and i-q[hh]+1>k: hh+=1 while hh<=tt and a[q[tt]] <= a[i]: tt-=1 tt+=1 q[tt]=i if i>=k: print(a[q[hh]], end=" ") KMP m = len(p) # 假设p为模板串,长度为m n = len(s) # 假设s为模式串,长度为n ne = [0] * (m + 1) # 初始化ne数组 # 求Next数组 j = 0 for i in range(2, m + 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, n + 1): while j and s[i] != p[j + 1]: j = ne[j] if s[i] == p[j + 1]: j += 1 if j == m: j = ne[j] # 匹配成功后的逻辑 n = int(input()) p = ' ' + input() m = int(input()) s = ' ' + input() ne = [0]*(n+1) 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 res = [] 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: res.append(i-j) j = ne[j] print(*res, sep=' ') Z函数 def z_function(s): n = len(s) z = [0] * n l, r = 0, 0 for i in range(1, n): if i <= r and z[i - l] < r - i + 1: z[i] = z[i - l] else: z[i] = max(0, r - i + 1) while i + z[i] < n and s[z[i]] == s[i + z[i]]: z[i] += 1 if i + z[i] - 1 > r: l = i r = i + z[i] - 1 return z Tire N = 100010 son = [[0] * 26 for _ in range(N)] cnt = [0] * N idx = 0 # 0号点既是根节点,又是空节点 # son[][]存储树中每个节点的子节点 # cnt[]存储以每个节点结尾的单词数量 # 插入一个字符串 def insert(s): global idx p = 0 for i in range(len(s)): u = ord(s[i]) - ord('a') if not son[p][u]: idx += 1 son[p][u] = idx p = son[p][u] cnt[p] += 1 # 查询字符串出现的次数 def query(s): p = 0 for i in range(len(s)): u = ord(s[i]) - ord('a') if not son[p][u]: return 0 p = son[p][u] return cnt[p] 马拉车(字符串回文串算法) class Solution: # 推荐教学视频 :https://www.bilibili.com/video/BV1Sx4y1k7jG/?spm_id_from=333.337.search-card.all.click&vd_source=a4a2b56f746715b34521bfb853094cf4 def longestPalindrome(self, s: str) -> str: s = '#' + '#'.join(list(s)) + '#' n = len(s) p = [0]*n #每个点的 最长回文字串 能到的 两侧长度 c, r = 0, 0 # 右边能到达最远的蘑菇的位置 和 其最右边能达到的位置 for i in range(n): if i<=r: p[i] = min(r-i, p[c + c-i]) # 由已知条件得到当前位置能达到的最大右侧距离( 需要取min(镜像位置的值, 当前最大蘑菇能覆盖到的最大值) ) while i+p[i]+1 < n and s[i-p[i]-1] == s[i+p[i]+1]: p[i]+=1 if p[i]+i > r: r = p[i] + i c = i ma = max(p) idx = p.index(ma) return s[idx-ma+1:idx+ma+1:2] 并查集 N = 1000005 # 假设N的值为1000005 p = [0] * N # 初始化p数组 # 返回x的祖宗节点 def find(x): if p[x] != x: p[x] = find(p[x]) return p[x] ''' 非递归写法 def find(x): while p[x]!=x: p[x] = p[p[x]] x = p[x] return x ''' # 初始化,假定节点编号是1~n for i in range(1, n + 1): p[i] = i # 合并a和b所在的两个集合 p[find(a)] = find(b) 维护size信息
...