Skip to content

Commit e4a961e

Browse files
committed
feat: add solutions to lc problem: No.0834
No.0834.Sum of Distances in Tree
1 parent 8dc3a5a commit e4a961e

File tree

10 files changed

+552
-6
lines changed

10 files changed

+552
-6
lines changed

solution/0500-0599/0552.Student Attendance Record II/README_EN.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ class Solution:
7373
ans += dfs(i + 1, j, k + 1)
7474
ans += dfs(i + 1, j, 0)
7575
return ans % mod
76-
76+
7777
mod = 10**9 + 7
7878
ans = dfs(0, 0, 0)
7979
dfs.cache_clear()
@@ -266,7 +266,7 @@ class Solution {
266266
public:
267267
int checkRecord(int n) {
268268
this->n = n;
269-
memset(f, -1, sizeof(f));
269+
memset(f, -1, sizeof(f));
270270
return dfs(0, 0, 0);
271271
}
272272

solution/0600-0699/0656.Coin Path/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,9 @@
5151

5252
题目需要我们找到从下标 1 到下标 n 的最小花费路径,且字典序最小,我们可以使用动态规划求解。
5353

54-
我们定义 $f[i]$ 表示从下标 $i$ 到下标 $n-1$ 的最小花费。如果 $coins[n - 1] = -1$,则不存在从下标 $n-1$ 到下标 $n-1$ 的路径,直接返回空数组即可。否则$f[n - 1] = coins[n - 1]$。
54+
我们定义 $f[i]$ 表示从下标 $i$ 到下标 $n-1$ 的最小花费。如果 $coins[n - 1] = -1$,则不存在从下标 $n-1$ 到下标 $n-1$ 的路径,直接返回空数组即可。否则 $f[n - 1] = coins[n - 1]$。
5555

56-
接下来,我们从下标 $n-2$ 开始,逆向遍历数组,对于下标 $i$,如果 $coins[i] = -1$,则 $f[i] = \infty$,否则$f[i] = \min_{j = i + 1}^{min(n - 1, i + maxJump)} f[j] + coins[i]$。
56+
接下来,我们从下标 $n-2$ 开始,逆向遍历数组,对于下标 $i$,如果 $coins[i] = -1$,则 $f[i] = \infty$,否则 $f[i] = \min_{j = i + 1}^{min(n - 1, i + maxJump)} f[j] + coins[i]$。
5757

5858
然后我们判断 $f[0]$ 是否为 $\infty$,如果是,则不存在一条满足条件的路径,返回空数组即可。否则,我们的总花费为 $s = f[0]$,我们从下标 0 开始,向后遍历数组,如果 $f[i] = s$,则说明从下标 $i$ 到下标 $n-1$ 的花费为 $s$,我们将 $s$ 减去 $coins[i]$,并将下标 $i+1$ 加入到结果数组中,直到遍历到下标 $n-1$,返回结果数组即可。
5959

solution/0800-0899/0834.Sum of Distances in Tree/README.md

Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,22 +57,215 @@
5757

5858
<!-- 这里可写通用的实现逻辑 -->
5959

60+
**方法一:树形 DP(换根)**
61+
62+
我们先跑一遍 DFS,计算出每个节点的子树大小,记录在数组 $size$ 中,并且统计出节点 $0$ 到其他节点的距离之和,记录在 $ans[0]$ 中。
63+
64+
接下来,我们再跑一遍 DFS,枚举每个点作为根节点时,其他节点到根节点的距离之和。假设当前节点 $i$ 的答案为 $t$,当我们从节点 $i$ 转移到节点 $j$ 时,距离之和变为 $t - size[j] + n - size[j]$,即距离节点 $j$ 及其子树节点的距离之和减少 $size[j]$,而距离其它节点的距离之和增加 $n - size[j]$。
65+
66+
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为树的节点数。
67+
68+
相似题目:
69+
70+
- [2581. 统计可能的树根数目](/solution/2500-2599/2581.Count%20Number%20of%20Possible%20Root%20Nodes/README.md)
71+
6072
<!-- tabs:start -->
6173

6274
### **Python3**
6375

6476
<!-- 这里可写当前语言的特殊实现逻辑 -->
6577

6678
```python
79+
class Solution:
80+
def sumOfDistancesInTree(self, n: int, edges: List[List[int]]) -> List[int]:
81+
def dfs1(i: int, fa: int, d: int):
82+
ans[0] += d
83+
size[i] = 1
84+
for j in g[i]:
85+
if j != fa:
86+
dfs1(j, i, d + 1)
87+
size[i] += size[j]
6788

89+
def dfs2(i: int, fa: int, t: int):
90+
ans[i] = t
91+
for j in g[i]:
92+
if j != fa:
93+
dfs2(j, i, t - size[j] + n - size[j])
94+
95+
g = defaultdict(list)
96+
for a, b in edges:
97+
g[a].append(b)
98+
g[b].append(a)
99+
100+
ans = [0] * n
101+
size = [0] * n
102+
dfs1(0, -1, 0)
103+
dfs2(0, -1, ans[0])
104+
return ans
68105
```
69106

70107
### **Java**
71108

72109
<!-- 这里可写当前语言的特殊实现逻辑 -->
73110

74111
```java
112+
class Solution {
113+
private int n;
114+
private int[] ans;
115+
private int[] size;
116+
private List<Integer>[] g;
117+
118+
public int[] sumOfDistancesInTree(int n, int[][] edges) {
119+
this.n = n;
120+
g = new List[n];
121+
ans = new int[n];
122+
size = new int[n];
123+
Arrays.setAll(g, k -> new ArrayList<>());
124+
for (var e : edges) {
125+
int a = e[0], b = e[1];
126+
g[a].add(b);
127+
g[b].add(a);
128+
}
129+
dfs1(0, -1, 0);
130+
dfs2(0, -1, ans[0]);
131+
return ans;
132+
}
133+
134+
private void dfs1(int i, int fa, int d) {
135+
ans[0] += d;
136+
size[i] = 1;
137+
for (int j : g[i]) {
138+
if (j != fa) {
139+
dfs1(j, i, d + 1);
140+
size[i] += size[j];
141+
}
142+
}
143+
}
144+
145+
private void dfs2(int i, int fa, int t) {
146+
ans[i] = t;
147+
for (int j : g[i]) {
148+
if (j != fa) {
149+
dfs2(j, i, t - size[j] + n - size[j]);
150+
}
151+
}
152+
}
153+
}
154+
```
155+
156+
### **C++**
157+
158+
```cpp
159+
class Solution {
160+
public:
161+
vector<int> sumOfDistancesInTree(int n, vector<vector<int>>& edges) {
162+
vector<vector<int>> g(n);
163+
for (auto& e : edges) {
164+
int a = e[0], b = e[1];
165+
g[a].push_back(b);
166+
g[b].push_back(a);
167+
}
168+
vector<int> ans(n);
169+
vector<int> size(n);
170+
171+
function<void(int, int, int)> dfs1 = [&](int i, int fa, int d) {
172+
ans[0] += d;
173+
size[i] = 1;
174+
for (int& j : g[i]) {
175+
if (j != fa) {
176+
dfs1(j, i, d + 1);
177+
size[i] += size[j];
178+
}
179+
}
180+
};
181+
182+
function<void(int, int, int)> dfs2 = [&](int i, int fa, int t) {
183+
ans[i] = t;
184+
for (int& j : g[i]) {
185+
if (j != fa) {
186+
dfs2(j, i, t - size[j] + n - size[j]);
187+
}
188+
}
189+
};
190+
191+
dfs1(0, -1, 0);
192+
dfs2(0, -1, ans[0]);
193+
return ans;
194+
}
195+
};
196+
```
197+
198+
### **Go**
199+
200+
```go
201+
func sumOfDistancesInTree(n int, edges [][]int) []int {
202+
g := make([][]int, n)
203+
for _, e := range edges {
204+
a, b := e[0], e[1]
205+
g[a] = append(g[a], b)
206+
g[b] = append(g[b], a)
207+
}
208+
ans := make([]int, n)
209+
size := make([]int, n)
210+
var dfs1 func(i, fa, d int)
211+
dfs1 = func(i, fa, d int) {
212+
ans[0] += d
213+
size[i] = 1
214+
for _, j := range g[i] {
215+
if j != fa {
216+
dfs1(j, i, d+1)
217+
size[i] += size[j]
218+
}
219+
}
220+
}
221+
var dfs2 func(i, fa, t int)
222+
dfs2 = func(i, fa, t int) {
223+
ans[i] = t
224+
for _, j := range g[i] {
225+
if j != fa {
226+
dfs2(j, i, t-size[j]+n-size[j])
227+
}
228+
}
229+
}
230+
dfs1(0, -1, 0)
231+
dfs2(0, -1, ans[0])
232+
return ans
233+
}
234+
```
235+
236+
### **TypeScript**
75237

238+
```ts
239+
function sumOfDistancesInTree(n: number, edges: number[][]): number[] {
240+
const g: number[][] = Array.from({ length: n }, () => []);
241+
for (const [a, b] of edges) {
242+
g[a].push(b);
243+
g[b].push(a);
244+
}
245+
const ans: number[] = new Array(n).fill(0);
246+
const size: number[] = new Array(n).fill(0);
247+
const dfs1 = (i: number, fa: number, d: number) => {
248+
ans[0] += d;
249+
size[i] = 1;
250+
for (const j of g[i]) {
251+
if (j !== fa) {
252+
dfs1(j, i, d + 1);
253+
size[i] += size[j];
254+
}
255+
}
256+
};
257+
const dfs2 = (i: number, fa: number, t: number) => {
258+
ans[i] = t;
259+
for (const j of g[i]) {
260+
if (j != fa) {
261+
dfs2(j, i, t - size[j] + n - size[j]);
262+
}
263+
}
264+
};
265+
dfs1(0, -1, 0);
266+
dfs2(0, -1, ans[0]);
267+
return ans;
268+
}
76269
```
77270

78271
### **...**

0 commit comments

Comments
 (0)