LC 6211. 创建价值相同的连通块
https://leetcode.cn/contest/biweekly-contest-89/problems/create-components-with-same-value/
这题迟迟不敢下手,也是不知道里面有什么玄机。看了第一名的题解,大致确定思路就是枚举所有可能的价值,然后验证这个价值是否可以满足。
我之前没有太写过这种在树上的DFS算法,看了第一名题解,觉得相比图的遍历可以简化不少:不用维护visited, 只需要记录parent就行,访问的时候避开parent.
然后这个验证过程也很有技巧:
- 先验证子树是否满足,假设子树返回值是r
- 如果 r<target 的话,那么就需要累加到当前节点上来,否则子树是无法独立满足条件的
- 如果 r>target 的话,那么直接返回 false.
- 如果 r == target 的话,那么子树可以独立出去认为返回值是0.
- 将无法独立出去的子树 r 累加,和当前节点相加,进行判断。
看了他写的代码之后觉得非常简单,但是遍历和子树拆解纠缠在一起,就迟迟不敢下手。
class Solution: def componentValue(self, nums: List[int], edges: List[List[int]]) -> int: n = len(nums) adj = [[] for _ in range(n)] for x, y in edges: adj[x].append(y) adj[y].append(x) def dfs(x, parent, target): s = nums[x] for y in adj[x]: if y == parent: continue res = dfs(y, x, target) if res < 0: return -1 s += res if s > target: return -1 if s == target: return 0 return s M = max(nums) total = sum(nums) part = total // M for p in reversed(range(1, part + 1)): if total % p == 0: target = total // p assert target >= M if dfs(0, -1, target) == 0: return p - 1