Kimi LeetCode 2440.创建价值相同的连通块 Python3实现
这是 LeetCode 2440. Create Components With Same Value(创建价值相同的连通块)的 Python3 实现。
题目理解
给定一棵无向树,每个节点有一个值 `nums[i]`。可以删除一些边,将树分成多个连通块。要求每个连通块的价值(块内所有节点值之和)相等。返回最多可以删除多少条边(即连通块数减1)。
核心思路
关键观察:
- 设总和为 `s`,分成 `k` 个连通块,则每个块的价值必须是 `s / k`
- 删除的边数 = `k - 1`,所以要最大化删除边数,就要最大化 `k`
- `k` 的最大可能值受限于:每个块至少包含一个节点,且每个块的价值至少为 `max(nums)`,所以 `k <= min(n, s / max(nums))`
算法:
1. 从大到小枚举连通块数量 `k`
2. 对于每个 `k`,检查 `s % k == 0`,则目标价值 `t = s // k`
3. 用 DFS 自底向上计算每个子树的和:
- 如果子树和恰好等于 `t`,说明可以在此处切断,返回 0(表示子树和已清零)
- 如果子树和大于 `t`,说明无法分割,返回 -1
- 否则返回子树和,继续向上累积
4. 如果根节点返回 0,说明可以成功分成 `k` 块,返回 `k - 1`
Python3 代码
```python
from typing import List
from collections import defaultdict
class Solution:
def componentValue(self, nums: List[int], edges: List[List[int]]) -> int:
def dfs(i: int, fa: int) -> int:
"""
返回以i为根的子树的累积和
- 如果子树和恰好等于t,返回0(表示可以在此处切断)
- 如果子树和大于t,返回-1(表示无法分割)
- 否则返回子树和,继续向上累积
"""
x = nums[i]
for j in g[i]:
if j != fa:
y = dfs(j, i)
if y == -1: # 子树无法分割
return -1
x += y
if x > t: # 累积和超过目标值,无法分割
return -1
# 如果恰好等于目标值,返回0(切断);否则返回累积和
return x if x < t else 0
n = len(nums)
# 构建邻接表
g = defaultdict(list)
for a, b in edges:
g[a].append(b)
g[b].append(a)
s = sum(nums) # 总和
mx = max(nums) # 最大值
# 从大到小枚举连通块数量k
# k的上限:每个块至少一个节点(n),且每个块价值至少为mx (s//mx)
for k in range(min(n, s // mx), 1, -1):
if s % k == 0: # 必须能整除
t = s // k # 每个连通块的目标价值
if dfs(0, -1) == 0: # 根节点返回0,表示成功分割
return k - 1 # 删除的边数 = 连通块数 - 1
return 0 # 无法分割,删除0条边
```
复杂度分析
项目 复杂度
时间 O(n × √s) — 枚举 `k` 的因子,每次 DFS 遍历整棵树
空间 O(n) — 邻接表和递归栈空间
其中 `n <= 2 × 10^4`,`nums[i] <= 50`,所以 `s <= 10^6`,完全可以通过。
更多推荐


所有评论(0)