class UF():
def __init__(self, n):
self.count = n
self._parent = [0] * n
self._weight = [0] * n
for i in range(n):
self._parent[i] = i
self._weight[i] = 1
def connect(self, p, q):
rootP = self.find(p)
rootQ = self.find(q)
if rootP == rootQ:
return
# 轻根到重根,为了平衡
if self._weight[rootP] > self._weight[rootQ]:
self._parent[rootQ] = rootP
self._weight[rootP] += self._weight[rootQ]
else:
self._parent[rootP] = rootQ
self._weight[rootQ] += self._weight[rootP]
self.count -= 1
def is_connected(self, p, q):
return self.find(p) == self.find(q)
def find(self, x):
while self._parent[x] != x:
# 路径压缩
self._parent[x] = self._parent[self._parent[x]]
x = self._parent[x]
return x
def get_count(self):
return self.count
还是人家的模板好用啊,等有空我要整理一套,下次力扣周赛用着顺手。嘻嘻
二维前缀和的板子。
class NumMatrix:
def __init__(self, matrix: List[List[int]]):
self.r = len(matrix)
self.c = len(matrix[0])
self.mas = [[0 for i in range(self.c+1)] for j in range(self.r+1)]
for i in range(1, self.r+1):
for j in range(1, self.c+1):
self.mas[i][j] += matrix[i-1][j-1]
for i in range(1, self.r+1):
for j in range(1, self.c+1):
self.mas[i][j] += self.mas[i-1][j] + self.mas[i][j-1] - self.mas[i-1][j-1]
print(self.mas)
def sumRegion(self, row1: int, col1: int, row2: int, col2: int) -> int:
return self.mas[row2+1][col2+1] - self.mas[row2+1][col1] - self.mas[row1][col2+1] + self.mas[row1][col1]
二分查找的板子
在单调递增序列a中查找x的数中最小的一个(即 x 或者 x的后继):
while l < r:
mid = (l + r) >> 1
if a[mid] >= x:
r = mid
else:
l = mid + 1
return a[l]
在单调递增序列a中查找x的数中最大的一个(即 x 或者 x的前驱):
while l < r:
mid = (l + r + 1) >> 1
if a[mid] <= x:
l = mid
else:
r = mid - 1
return a[l]
二分图,图染色
class Solution:
def possibleBipartition(self, n: int, dislikes: List[List[int]]) -> bool:
adj = defaultdict(list)
color = [0 for i in range(0, n+1)]
for u, v in dislikes:
adj[u].append(v)
adj[v].append(u)
def dfs(u, c):
color[u] = c
for v in adj[u]:
if color[v] == 0:
a = dfs(v, 3-c)
if not a :return a
elif color[u] == color[v]:
return False
return True
for i in range(1, n+1):
if color[i] == 0:
a = dfs(i, 1)
if not a: return a
return True
差分->大数据量
class Solution:
def fullBloomFlowers(self, flowers: List[List[int]], persons: List[int]) -> List[int]:
diff = defaultdict(int)
for st, ed in flowers:
diff[st] += 1
diff[ed+1] -= 1
time = sorted(diff.keys())
n = len(persons)
i = 0
su = 0
ans = [0 for i in range(n)]
for t, ix in sorted(zip(persons, range(n))):
while i < len(time) and time[i] <= t:
su += diff[time[i]]
i += 1
ans[ix] = su
return ans
最短路径问题
class Solution:
def minimumObstacles(self, grid: List[List[int]]) -> int:
m, n = len(grid), len(grid[0])
val = [[float('inf') for i in range(n)] for j in range(m)]
q = deque()
q.append((0, 0, 0))
ans = float('inf')
vec = [(1, 0), (-1, 0), (0, -1), (0, 1)]
while q:
x, y, w = q.popleft()
if x == m - 1 and y == n - 1:
ans = min(ans, w)
if w > val[x][y]: continue
for v in vec:
xx, yy = x + v[0], y + v[1]
if 0<=xx<m and 0<=yy<n and w + grid[xx][yy] < val[xx][yy]:
val[xx][yy] = w + grid[xx][yy]
q.append((xx, yy, w + grid[xx][yy]))
return ans
线段树模板,区间修改
#模板
def lowbit(x: int) -> int:
return x & (-x)
class BIT2:
# 区间add, 单点求值, 范围[0, n - 1]
def __init__(self, n: int):
self.n = n
self.tree = [0] * (n + 2)
def _add(self, x: int, k: int):
while x <= self.n:
self.tree[x] += k
x += lowbit(x)
def get(self, x: int): # 获取单点值, 范围 [0, n-1]
x += 1
res = 0
while x > 0:
res += self.tree[x]
x -= lowbit(x)
return res
def add_range(self, x: int, y: int, k: int): # 区间加k, 范围 [0, n-1]
x += 1
y += 1
self._add(x, k)
self._add(y + 1, -k)
求二进制的子集和补集
# 子集
j = (n - 1) & n
while j:
ans.append(j)
j = (j - 1) & n
# 子集和补集
for (int j = (i - 1) & i; j > 0; j = (j - 1) & i)
f[i] = min(f[i], f[j] + f[i ^ j]);
字典树(trie)
class Trie:
def __init__(self):
self.child = [None for i in range(26)]
self.end = False
def insert(self, word: str) -> None:
rt = self
for c in word:
ch = ord(c) - ord('a')
if rt.child[ch] == None:
rt.child[ch] = Trie()
rt = rt.child[ch]
rt.end = True
def searchPrefix(self, word: str) -> bool:
rt = self
for c in word:
ch = ord(c) - ord('a')
if rt.child[ch] == None:
return None
rt = rt.child[ch]
return rt
def search(self, word:str) -> bool:
node = self.searchPrefix(word)
return node is not None and node.end
def startsWith(self, prefix: str) -> bool:
return self.searchPrefix(prefix) is not None