Given a tree, return a vector, with each elements of the vector is the sum of the distances between the corresponding node and all other nodes.
Intuition
Intuitively, I want to use DFS + memorization to solve the problem, however, such method exceeds te time limit.
Then, I refer to some solutions, and solve the problem.
Approach
DP -> TLE
In the first, I am thinking that we can use dp[i][j]
to represent the distance between the node i
and the node j
. Initially, dp
are initialized as follows:
- If there is an edge between
i
andj
, thendp[i][j]=dp[j][i]=1
. - If there is an edge between
i
andj
, thendp[i][j]=dp[j][i]=INFINITY
.
we traversal from node 0
to node n-1
, for each node i
, we compute the distance between i
and all other nodes j
. There are two cases:
dp[i][j] != INFINITY
, then we directly returnsdp[i][j]
dp[i][j] == INFINITY
, then it means the distance between nodei
and nodej
hasn’t been computed, we then update it as follows:
$$ dp[i][j] = \min_{k\in N(i)} (1 + dp[k][j]) $$
where $N(i)$ is the nodes that adjacent to node i
. The min
operation is used here since the node k
and the node j
may not connected (without passing node i
).
The code is given as follows. However, the time complexity is $O(n^2)$, which exceeds the time limit.
|
|
Tree + Traversal
The second way is not easy to figure out. We decompose it into two parts:
- compute the distance between the root node and all other nodes.
- Convert the root node from one to another and update the result.
Sum of distance from root node to all other nodes.
Consider one example tree with root set as 0
:
|
|
We first define dist[i]
as the distance of all child nodes of node i
to node i
. Then we have:
- $dist[i] = 0$ if
i
is a leaf node. - $dist[i] = \sum_{j\in C(i)}dist[j] + |C(i)|$ if
i
is not a leaf node, where $C(i)$ is the offspring of nodei
We can now compute the sum of distances between root 0
to all other nodes, which is result[0]
.
Now we need to compute all other results. Repeating the above process is too time consuming, we need to reduce the time complexity. We are seeking a way to compute result[i]
from result[j]
, where $j\in C(i)$.
Note that for $k\in C(j)$, when we compute result[i]
, we are computing distance from $k$ to $i$, so we need to reduce by 1 since their height decreases (the root changes from i
to j
). On the other hand, all other nodes, which are not offspring of node j
, is added by 1 since the height of them increases. Thus, the transformation reads:
$$ result[j] = result[i] - |C(j)| + n - |C(j)| $$
Complexity
Time complexity: visited all nodes twice. $$ O(n) $$
Space complexity: use two vectors of size $n$ to store the result. $$ O(n) $$
Code
|
|