Skip to content

Commit 9512a6c

Browse files
committed
feat: add 834
1 parent cfa95da commit 9512a6c

File tree

3 files changed

+128
-2
lines changed

3 files changed

+128
-2
lines changed

Hard/834 Sum of Distances in Tree.md

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,71 @@
22

33
## Intuition
44

5+
A key observation is that we can leverage the tree structure and parent-child relationships to compute these sums efficiently. Instead of calculating distances from scratch for each node, we can use the results from a parent node to derive the results for its children.
6+
57
## Approach
68

9+
The solution uses a two-pass DFS approach:
10+
11+
1. First DFS (dfs1):
12+
- Calculates the number of child nodes for each node
13+
- Computes the initial sum of distances for the root node (0)
14+
- This pass builds the foundation for the second pass
15+
2. Second DFS (dfs2):
16+
- Uses the results from the first pass to compute distances for all other nodes
17+
- For each child node, the sum of distances can be derived from its parent's sum using the formula:
18+
`ret[child] = ret[parent] + (n - 2 * childNodes[child])`
19+
- This formula works because moving from parent to child:
20+
- Increases distance by 1 for all nodes not in the child's subtree
21+
- Decreases distance by 1 for all nodes in the child's subtree
22+
723
## Complexity
824

9-
- Time complexity:
10-
- Space complexity:
25+
- Time complexity: O(n)
26+
- Space complexity: O(n)
1127

1228
## Keywords
1329

30+
- DFS
31+
- Distance Calculation
32+
1433
## Code
1534

1635
```go
36+
func sumOfDistancesInTree(n int, edges [][]int) []int {
37+
ret, childNodes, tree := make([]int, n), make([]int, n), make([][]int, n)
38+
for _, edge := range edges {
39+
a, b := edge[0], edge[1]
40+
tree[a], tree[b] = append(tree[a], b), append(tree[b], a)
41+
}
42+
43+
var dfs1 func(cur, prev int)
44+
dfs1 = func(cur, prev int) {
45+
childNodes[cur] = 1
46+
for _, neighbor := range tree[cur] {
47+
if neighbor == prev {
48+
continue
49+
}
50+
dfs1(neighbor, cur)
51+
childNodes[cur] += childNodes[neighbor]
52+
ret[cur] += ret[neighbor] + childNodes[neighbor]
53+
}
54+
}
55+
56+
var dfs2 func(cur, prev int)
57+
dfs2 = func(cur, prev int) {
58+
for _, neighbor := range tree[cur] {
59+
if neighbor == prev {
60+
continue
61+
}
62+
ret[neighbor] = ret[cur] + (n- 2 * childNodes[neighbor])
63+
dfs2(neighbor, cur)
64+
}
65+
}
66+
67+
dfs1(0, -1)
68+
dfs2(0, -1)
1769

70+
return ret
71+
}
1872
```

Week8/834 AC.png

40.1 KB
Loading

Week8/834 Sum of Distances in Tree.md

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# 834. Sum of Distances in Tree
2+
3+
## Intuition
4+
5+
A key observation is that we can leverage the tree structure and parent-child relationships to compute these sums efficiently. Instead of calculating distances from scratch for each node, we can use the results from a parent node to derive the results for its children.
6+
7+
## Approach
8+
9+
The solution uses a two-pass DFS approach:
10+
11+
1. First DFS (dfs1):
12+
- Calculates the number of child nodes for each node
13+
- Computes the initial sum of distances for the root node (0)
14+
- This pass builds the foundation for the second pass
15+
2. Second DFS (dfs2):
16+
- Uses the results from the first pass to compute distances for all other nodes
17+
- For each child node, the sum of distances can be derived from its parent's sum using the formula:
18+
`ret[child] = ret[parent] + (n - 2 * childNodes[child])`
19+
- This formula works because moving from parent to child:
20+
- Increases distance by 1 for all nodes not in the child's subtree
21+
- Decreases distance by 1 for all nodes in the child's subtree
22+
23+
## Complexity
24+
25+
- Time complexity: O(n)
26+
- Space complexity: O(n)
27+
28+
## Keywords
29+
30+
- DFS
31+
- Distance Calculation
32+
33+
## Code
34+
35+
```go
36+
func sumOfDistancesInTree(n int, edges [][]int) []int {
37+
ret, childNodes, tree := make([]int, n), make([]int, n), make([][]int, n)
38+
for _, edge := range edges {
39+
a, b := edge[0], edge[1]
40+
tree[a], tree[b] = append(tree[a], b), append(tree[b], a)
41+
}
42+
43+
var dfs1 func(cur, prev int)
44+
dfs1 = func(cur, prev int) {
45+
childNodes[cur] = 1
46+
for _, neighbor := range tree[cur] {
47+
if neighbor == prev {
48+
continue
49+
}
50+
dfs1(neighbor, cur)
51+
childNodes[cur] += childNodes[neighbor]
52+
ret[cur] += ret[neighbor] + childNodes[neighbor]
53+
}
54+
}
55+
56+
var dfs2 func(cur, prev int)
57+
dfs2 = func(cur, prev int) {
58+
for _, neighbor := range tree[cur] {
59+
if neighbor == prev {
60+
continue
61+
}
62+
ret[neighbor] = ret[cur] + (n- 2 * childNodes[neighbor])
63+
dfs2(neighbor, cur)
64+
}
65+
}
66+
67+
dfs1(0, -1)
68+
dfs2(0, -1)
69+
70+
return ret
71+
}
72+
```

0 commit comments

Comments
 (0)