forked from itcharge/AlgoNote
-
Notifications
You must be signed in to change notification settings - Fork 0
[pull] main from itcharge:main #124
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 1 commit
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
105 changes: 105 additions & 0 deletions
Solutions/0834. 树中距离之和.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
# [0834. 树中距离之和](https://leetcode.cn/problems/sum-of-distances-in-tree/) | ||
|
||
- 标签:树、深度优先搜索、图、动态规划 | ||
- 难度:困难 | ||
|
||
## 题目大意 | ||
|
||
**描述**:给定一个无向、连通的树。树中有 $n$ 个标记为 0ドル \sim n - 1$ 的节点以及 $n - 1$ 条边 。 | ||
|
||
给定整数 $n$ 和数组 $edges,ドル其中 $edges[i] = [ai, bi]$ 表示树中的节点 $ai$ 和 $bi$ 之间有一条边。 | ||
|
||
**要求**:返回长度为 $n$ 的数组 $answer,ドル其中 $answer[i]$ 是树中第 $i$ 个节点与所有其他节点之间的距离之和。 | ||
|
||
**说明**: | ||
|
||
- 1ドル \le n \le 3 \times 10^4$。 | ||
- $edges.length == n - 1$。 | ||
- $edges[i].length == 2$。 | ||
- 0ドル \le ai, bi < n$。 | ||
- $ai \ne bi$。 | ||
- 给定的输入保证为有效的树。 | ||
|
||
**示例**: | ||
|
||
- 示例 1: | ||
|
||
 | ||
|
||
```Python | ||
输入: n = 6, edges = [[0,1],[0,2],[2,3],[2,4],[2,5]] | ||
输出: [8,12,6,10,10,10] | ||
解释: 树如图所示。 | ||
我们可以计算出 dist(0,1) + dist(0,2) + dist(0,3) + dist(0,4) + dist(0,5) | ||
也就是 1 +たす 1 +たす 2 +たす 2 +たす 2 =わ 8。 因此,answer[0] = 8,以此类推。 | ||
``` | ||
|
||
- 示例 2: | ||
|
||
 | ||
|
||
```Python | ||
输入: n = 2, edges = [[1,0]] | ||
输出: [1,1] | ||
``` | ||
|
||
## 解题思路 | ||
|
||
### 思路 1:树形 DP + 二次遍历换根法 | ||
|
||
最容易想到的做法是:枚举 $n$ 个节点,以每个节点为根节点进行树形 DP。 | ||
|
||
对于节点 $u,ドル定义 $dp[u]$ 为:以节点 $u$ 为根节点的树,它的所有子节点到它的距离之和。 | ||
|
||
然后进行一轮深度优先搜索,在搜索的过程中得到以节点 $v$ 为根节点的树,节点 $v$ 与所有其他子节点之间的距离之和 $dp[v]$。还能得到以节点 $v$ 为子树的子节点个数 $sizes[v]$。 | ||
|
||
对于节点 $v$ 来说,其对 $dp[u]$ 的贡献为:节点 $v$ 与所有其他子节点之间的距离之和,再加上需要经过 $u \rightarrow v$ 这条边的节点个数,即 $dp[v] + sizes[v]$。 | ||
|
||
可得到状态转移方程为:$dp[u] = \sum_{v \in graph[u]}(dp[v] + sizes[v])$。 | ||
|
||
这样,对于 $n$ 个节点来说,需要进行 $n$ 次树形 DP,这种做法的时间复杂度为 $O(n^2),ドル而 $n$ 的范围为 $[1, 3 \times 10^4],ドル这样做会导致超时,因此需要进行优化。 | ||
|
||
我们可以使用「二次遍历换根法」进行优化,从而在 $O(n)$ 的时间复杂度内解决这道题。 | ||
|
||
第一次遍历: | ||
|
||
### 思路 1:代码 | ||
|
||
```Python | ||
class Solution: | ||
def sumOfDistancesInTree(self, n: int, edges: List[List[int]]) -> List[int]: | ||
graph = [[] for _ in range(n)] | ||
|
||
for u, v in edges: | ||
graph[u].append(v) | ||
graph[v].append(u) | ||
|
||
|
||
ans = [0 for _ in range(n)] | ||
|
||
sizes = [1 for _ in range(n)] | ||
def dfs(u, fa, depth): | ||
ans[0] += depth | ||
for v in graph[u]: | ||
if v == fa: | ||
continue | ||
dfs(v, u, depth + 1) | ||
sizes[u] += sizes[v] | ||
|
||
def reroot(u, fa): | ||
for v in graph[u]: | ||
if v == fa: | ||
continue | ||
ans[v] = ans[u] + n - 2 * size[v] | ||
reroot(v, u) | ||
|
||
dfs(0, -1, 0) | ||
reroot(0, -1) | ||
return ans | ||
``` | ||
|
||
### 思路 1:复杂度分析 | ||
|
||
- **时间复杂度**:$O(n),ドル其中 $n$ 为树的节点个数。 | ||
- **空间复杂度**:$O(n)$。 | ||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.