Problem
There is an undirected connected tree with n nodes labeled from 0 to n - 1 and n - 1 edges.
You are given the integer n and the array edges where edges[i] = [ai, bi] indicates that there is an edge between nodes ai and bi in the tree.
Return an array answer of length n where answer[i] is the sum of the distances between the ith node in the tree and all other nodes.
Examples
Example 1:
graph TD; 0 --- 1 & 2 2 --- 3 & 4 & 5
| |
Example 2:
graph TD; 0
| |
Example 3:
graph TD; 0 --- 1
| |
Solution
Method 1 - Pre-order and Post-order Traversal
Solve for root
Lets start with example 1, and lets say we have to find the sum of distances only for root node.
graph TD; 0 --- 1 & 2 2 --- 3 & 4 & 5 style 0 fill:#f9f
Then, we can see following:
| |
sumOfDistance(1) means distance, when 1 is root (see tree below), and it is 0 because it doesn’t have any child.
graph TD; 1 style 1 fill:#f9f
sumOfDistance(2) is 3, because we can see it has 3 children, all as leaf (see below)
graph TD; 2 --- 3 & 4 & 5 style 2 fill:#f9f
We are adding the number of nodes of subtree because every node in subtree will be 1 unit more far from the original root.
For eg. for subtree with 2 as root, distance from 0 adds 4:
We need two arrays cnt and ans. cnt will store the number of nodes in each subtree and ans will the store the answer as discussed above. Below is the code.
Original Solution
We can run the dfs function above for every node and get the solution. This will result in O(N * N) time complexity. We can do this in O(N) time using a technique popularly known as re-rooting technique.
Suppose, instead of 0 as root, we take 2 as root. What changes will we observe?
graph TD; 2 --- 0 & 3 & 4 & 5 0 --- 1 style 2 fill:#f9f
cnt[2] nodes got closer by 1 unit to new root, and n - cnt[2] nodes got farther by 1 unit from new root.
| |
i.e.
| |
Refer to dfs2 function for that.
Code
| |
Complexity
- Time:
O(N)- for both dfs - Space:
O(N)