算法题模板

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值