LeetCode Weekly Contest 457

本文最后更新于 2 分钟前,文中所描述的信息可能已发生改变。

3606. 优惠券校验器 - 力扣(LeetCode)

解题思路

模拟即可

示例代码

python
class Solution:
    def validateCoupons(self, code: List[str], businessLine: List[str], isActive: List[bool]) -> List[str]:
        d = {"electronics": 0, "grocery": 1, "pharmacy": 2, "restaurant": 3}
        def check(s):
            for c in s:
                if c != '_' and not c.isalpha() and not c.isdigit():
                    return False
            return len(s) > 0

        ans = []
        for s, b, f in zip(code, businessLine, isActive):
            if check(s) and b in d and f:
                ans.append((s, b))
        ans.sort(key=lambda p: (d[p[1]], p[0]))
        return [s for s, _ in ans]

3607. 电网维护 - 力扣(LeetCode)

解题思路

查找连通块,用 dfs 或用并查集,而后用堆维护每一个连通块的最小编号(懒删除)

示例代码

python
class Solution:
    def processQueries(self, c: int, connections: List[List[int]], queries: List[List[int]]) -> List[int]:

        g = [[] for _ in range(c + 1)]
        for u, v in connections:
            g[u].append(v)
            g[v].append(u)

        def dfs(x, fa):
            for y in g[x]:
                if y in vis or y == fa:
                    continue
                heappush(hs[-1], y)
                d[y] = len(hs) - 1
                vis.add(y)
                dfs(y, x)
            return

        vis = set()
        hs = []
        d = {}
        for i in range(1, c + 1):
            if i not in vis:
                hs.append([])
                vis.add(i)
                heappush(hs[-1], i)
                d[i] = len(hs) - 1
                dfs(i, 0)

        ans = []
        dis = set()
        for op, x in queries:
            if op == 1:
                if x not in dis:
                    ans.append(x)
                else:
                    ans.append(-1)
                    if x not in d:
                        continue
                    while hs[d[x]]:
                        y = hs[d[x]][0]
                        if y in dis:
	                        heappop(hs[d[x]])
	                    else:
                            ans[-1] = y
                            break
            else:
                dis.add(x)
        return ans
python
class Solution:
    def processQueries(self, c: int, connections: List[List[int]], queries: List[List[int]]) -> List[int]:
        uf = UnionFind(c + 1)
        for u, v in connections:
            uf.union_rank(u, v)

        hs = [[] for _ in range(c + 1)]
        for i in range(1, c + 1):
            hs[uf.find(i)].append(i)

        ans = []
        dis = set()
        for op, u in queries:
            if op == 1:
                if u not in dis:
                    ans.append(u)
                else:
                    ans.append(-1)
                    v = uf.find(u)
                    while hs[v]:
                        if hs[v][0] in dis:
                            heappop(hs[v])
                        else:
                            ans[-1] = hs[v][0]
                            break
            else:
                dis.add(u)
        return ans

3608. 包含 K 个连通分量需要的最小时间 - 力扣(LeetCode)

解题思路

正难则反,按消失时间排序边,遍历加入并查集,当连通块个数小于 k 时退出遍历或返回答案

示例代码

python
class Solution:
    def minTime(self, n: int, edges: List[List[int]], k: int) -> int:
        edges.sort(key=lambda p: -p[-1])
        uf = UnionFind(n)
        cnt = n
        for u, v, t in edges:
            if not uf.connected(u, v):
                cnt -= 1
                uf.union_rank(u, v)
                if cnt and cnt < k:
                    return t
        return 0
py
class UnionFind:
    def __init__(self, n: int) -> None:
        self.n = n
        self.parent = list(range(n))
        self.rank = [1] * n
        self.size = [1] * n

    def find(self, x: int) -> int:
        if self.parent[x] == x:
            return x
        self.parent[x] = self.find(self.parent[x])
        return self.parent[x]

    def union_by_size(self, x: int, y: int) -> None:
        x_root, y_root = self.find(x), self.find(y)
        if x_root != y_root:
            if self.size[y_root] <= self.size[x_root]:
                self.parent[y_root] = x_root
                self.size[x_root] += self.size[y_root]
            else:
                self.parent[x_root] = y_root
                self.size[y_root] += self.size[x_root]

    def union_rank(self, x: int, y: int) -> None:
        x_root, y_root = self.find(x), self.find(y)
        if x_root != y_root:
            if self.rank[y_root] <= self.rank[x_root]:
                self.parent[y_root] = x_root
            else:
                self.parent[x_root] = y_root
            if self.rank[x_root] == self.rank[y_root]:
                self.rank[x_root] += 1

    def connected(self, x: int, y: int) -> bool:
        return self.find(x) == self.find(y)

3609. 到达目标点的最小移动次数 - 力扣(LeetCode)

解题思路

脑筋急转弯,正难则反,计算 (tx, ty) -> (sx, sy)的最小移动次数

示例代码

python
class Solution:
    def minMoves(self, sx: int, sy: int, tx: int, ty: int) -> int:
        q = [(tx, ty)]
        ans = 0
        while q:
            tmp = q
            q = []
            for x, y in tmp:
                if x == sx and y == sy:
                    return ans
                if x < sx or y < sy:
                    continue
                if x > y:
                    if x >= y * 2:
                        if x % 2 == 0:
                            q.append((x // 2, y))
                    else:
                        q.append((x - y, y))
                elif x < y:
                    if y >= x * 2:
                        if y % 2 == 0:
                            q.append((x, y // 2))
                    else:
                        q.append((x, y - x))
                else:
                    q.append((x, y - x))
                    q.append((x - y, y))
            ans += 1
        return -1
LeetCode Weekly Contest 458
LeetCode Biweekly Contest 160