算法题模板

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中查找\geqslantx的数中最小的一个(即 x 或者 x的后继):

while l < r:
	mid = (l + r) >> 1
	if a[mid] >= x:
		r = mid 
	else:
		l = mid + 1
return a[l] 

在单调递增序列a中查找\leqslantx的数中最大的一个(即 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

### 关于算法模板题的练习 对于算法学习者而言,掌握一些经典问题的模板是非常重要的。通过这些模板题的学习和实践,能够帮助深入理解特定算法的核心思想及其应用方式。 #### BFS 和 DFS 的模板题 在广度优先搜索 (BFS) 中,常见的模板题涉及图遍历、最短路径等问题[^2]。例如: - **岛屿数量**:给定一个二维网格地图,计算其中有多少个由 '1' 表示的连通区域。 - **迷宫问题**:在一个矩阵中找到从起点到终点的最短路径。 而深度优先搜索 (DFS) 则适用于树结构、图遍历以及状态空间探索等问题[^3]。以下是几个典型的 DFS 模板题: - **N皇后问题**:放置 N 个皇后在棋盘上使得它们互不攻击。 - **括号生成**:给出 n 对括号,返回所有可能的有效组合。 ```python def dfs(node, visited): if node not in visited: visited.add(node) for neighbor in graph[node]: if neighbor not in visited: dfs(neighbor, visited) def bfs(start_node): queue = [start_node] visited = set([start_node]) while queue: current = queue.pop(0) for neighbor in graph[current]: if neighbor not in visited: visited.add(neighbor) queue.append(neighbor) ``` #### Bellman-Ford 算法的应用场景 Bellman-Ford 是一种用于解决单源最短路径问题的经典动态规划方法[^4]。它特别适合处理带负权边的情况,并能检测是否存在负权重环路。下面是一道与此相关的模板题: - **城市间旅行费用最小化**:输入若干个城市之间的距离表(含正负),求某两点间的最低成本路线;如果存在无法到达或陷入无限循环,则需报告异常情况。 ```python def bellman_ford(graph, source): distance = {node: float('inf') for node in graph} distance[source] = 0 for _ in range(len(graph)-1): for u in graph: for v, w in graph[u].items(): if distance[u] != float('inf') and distance[u] + w < distance[v]: distance[v] = distance[u] + w # Check for negative cycles for u in graph: for v, w in graph[u].items(): if distance[u] != float('inf') and distance[u] + w < distance[v]: raise ValueError("Graph contains a negative weight cycle") return distance ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值