本文内容来自于花花酱的公众号内容,现整理为博客如下。
1.二分搜索模板(Binary search template)
参考链接:https://zxi.mytechroad.com/blog/template/binary-search-template/
C++
// Author: Huahua
// Returns the smallest m in [l, r),
// s.t. cond(m) == True
// If not found returns r.
int binarySearch(int l, int r) {
while (l < r) {
int m = l + (r - l) / 2;
if (cond(m)) r = m;
else l = m + 1;
}
return l;
}
Python
# Author: Huahua
# Returns the smallest m in [l, r),
# s.t. cond(m) == True
# If not found returns r.
def binarySearch(l, r)
while l < r:
m = l + (r - l) // 2
if cond(m):
r = m
else
l = m + 1
return l
2.排列模板
Python
# Author: Huahua
def P(n, m, cur, used):
if len(cur) == m:
print(cur)
return
for i in range(n):
if used[i]: continue
used[i] = True
cur.append(i + 1)
P(n, m, cur, used)
cur.pop()
used[i] = False
n = 5
m = 3
P(n, m, [], [False] * n)
3.组合模板
Python
# Author: Huahua
def C(n, m, s, cur):
if len(cur) == m:
print(cur)
return
for i in range(s, n):
cur.append(i + 1)
C(n, m, i + 1, cur)
cur.pop()
n = 5
m = 3
C(n, m, 0, [])
4.BFS模板
Python
# Author: Huahua
# Find the shortest path from |start| to |target| in a unweighted graph G.
# neighbor(x) returns the neighbors of x in G.
q = deque([start])
seen = set([start])
steps = 0
while q:
size = len(q)
for _ in range(size):
n = q.popleft()
if n == target: return steps
for t in neighbor(n):
if t in seen: continue
q.append(t)
seen.add(t)
steps += 1
return -1 # not found
5.DFS模板
Python
# Author: Huahua
# Check whether there is a path from |start| to |target| in graph G.
# neighbor(x) returns the neighbors of x in G.
seen = set([start])
def dfs(n):
if n == target:
return True
for t in neighbor(n):
if t in seen: continue
seen.add(t)
if dfs(t): return True
seen.remove(t) # back-tracking
return False
return dfs(start)
6.前缀树模板
Python
# Author: Huahua
class Trie(object):
def __init__(self): self.root = {}
def insert(self, word):
p = self.root
for c in word:
if c not in p: p[c] = {}
p = p[c]
p['#'] = True
def search(self, word):
node = self._find(word)
return node and '#' in node
def startsWith(self, prefix):
return self._find(prefix)
def _find(self, prefix):
p = self.root
for c in prefix:
if c not in p: return None
p = p[c]
return p
7.并查集模板
Python
# Author: Huahua
class UnionFindSet:
def __init__(self, n):
self.p = [i for i in range(n + 1)]
self.r = [1 for i in range(n + 1)]
def find(self, u):
while u != self.p[u]:
self.p[u] = self.p[self.p[u]]
u = self.p[u]
return u
def union(self, u, v):
pu, pv = self.find(u), self.find(v)
if pu == pv: return False
if self.r[pu] < self.r[pv]:
self.p[pu] = pv
elif self.r[pu] > self.r[pv]:
self.p[pv] = pu
else:
self.p[pv] = pu
self.r[pu] += 1
return True
8.记忆化递归模板
Python
# Author: Huahua
# dp(state) returns the minimal cost to solve the subproblem |s|.
def dp(s):
# No solution
if unsolvable(s): return float('inf')
# Base case, easy to solve.
if base_case(s): return cost(s)
# Already solved
if s in memo: return memo[s]
best = float('inf')
for t in subproblems(s):
best = min(best, cost(s, t) + dp(t))
memo[s] = best
return best
return dp(start)
9.BIT模板
Python
# Author: Huahua
class Fenwick:
def __init__(self, n):
self.n = n
self.val = [0] * n
def query(self, i):
s = 0
while i > 0:
s += self.val[i]
i -= i & -i
return s
def update(self, i, delta):
while i < self.n:
self.val[i] += delta
i += i & -i
10.KMP模板
Python
# Author: Huahua
def Build(p):
m = len(p)
nxt = [0, 0]
j = 0
for i in range(1, m):
while j > 0 and p[i] != p[j]:
j = nxt[j]
if p[i] == p[j]:
j += 1
nxt.append(j)
return nxt
def Match(s, p):
n, m = len(s), len(p)
nxt = Build(p)
ans = []
j = 0
for i in range(n):
while j > 0 and s[i] != p[j]:
j = nxt[j]
if s[i] == p[j]:
j += 1
if j == m:
ans.append(i - m + 1)
j = nxt[j]
return ans