豆包 LeetCode 834.树中距离之和 public int[] sumOfDistancesInTree(int n, int[][] edges)
这是一道非常经典的 树形 DP + 换根 DP 难题,我直接给你 可提交的 Java 标准解法,思路清晰、一遍 AC。1. 先建图(树),用邻接表。核心公式(一定要背)
·
这是一道非常经典的 树形 DP + 换根 DP 难题,我直接给你 可提交的 Java 标准解法,思路清晰、一遍 AC。
题目思路
1. 先建图(树),用邻接表。
2. 第一次 DFS(后序):
- 计算以 0 为根时,每个子树的节点数 count[]
- 计算根到所有节点的距离和 res[0]
3. 第二次 DFS(前序/换根): - 从父节点推子节点:
res[child] = res[parent] - count[child] + (n - count[child])
Java 完整代码
java
import java.util.*;
class Solution {
List<List> graph;
int[] res;
int[] count;
int n;
public int[] sumOfDistancesInTree(int n, int[][] edges) {
this.n = n;
graph = new ArrayList<>();
for (int i = 0; i < n; i++) {
graph.add(new ArrayList<>());
}
for (int[] e : edges) {
int u = e[0], v = e[1];
graph.get(u).add(v);
graph.get(v).add(u);
}
res = new int[n];
count = new int[n];
Arrays.fill(count, 1);
// 第一次 DFS:以 0 为根,求 count 和 res[0]
dfs1(0, -1);
// 第二次 DFS:换根 DP
dfs2(0, -1);
return res;
}
// 后序:求子树大小 & 根 0 的总距离
void dfs1(int u, int parent) {
for (int v : graph.get(u)) {
if (v == parent) continue;
dfs1(v, u);
count[u] += count[v];
res[u] += res[v] + count[v];
}
}
// 前序:换根推导
void dfs2(int u, int parent) {
for (int v : graph.get(u)) {
if (v == parent) continue;
res[v] = res[u] - count[v] + (n - count[v]);
dfs2(v, u);
}
}
}
核心公式(一定要背)
从父 u → 子 v:
- 靠近 v 的 count[v] 个点 距离 -1
- 远离 v 的 n - count[v] 个点 距离 +1
所以:
res[v] = res[u] - count[v] + (n - count[v])
如果你需要,我可以再给你:
- 逐行注释版
- 手算模拟过程
- Python / C++ 版本
你想要哪个?
更多推荐




所有评论(0)