[LeetCode] 834. Sum of Distances in Tree


LeetCode刷題記錄

傳送門

Description

An undirected, connected treewith N nodes labelled 0...N-1 and N-1 edges are given.

The ith edge connects nodes edges[i][0] and edges[i][1] together.

Return a list ans, where ans[i] is the sum of the distances between node i and all other nodes.

Example 1:

Input: N = 6, edges = [[0,1],[0,2],[2,3],[2,4],[2,5]]
Output: [8,12,6,10,10,10]
Explanation: 
Here is a diagram of the given tree:
  0
 / \
1   2
   /|\
  3 4 5
We can see that dist(0,1) + dist(0,2) + dist(0,3) + dist(0,4) + dist(0,5)
equals 1 + 1 + 2 + 2 + 2 = 8.  Hence, answer[0] = 8, and so on.

Note: 1 <= N <= 10000

思路

題意:給出一棵樹,求出樹上每個節點到其他節點的距離總和。

題解:每個節點保存兩個值,一個是其子樹的節點個數(包括自身節點也要計數)nodesum[ ],一個是其子樹各點到它的距離 dp[ ],那么我們假設根節點為 u ,其僅有一個兒子 v , u 到 v 的距離為 1 ,而 v 有若干兒子節點,那么 dp[v] 表示 v 的子樹各點到 v 的距離和,那么各個節點到達 u 的距離便可以這樣計算: dp[u] = dp[v] + nodesum[ v ] *1; (式子的理解,v 的一個兒子節點為 f,那么 f 到達 u 的距離為  (sum[ f ->v] + sum [v- > u])*1 ,dp[v] 包含了 sum[f->v]*1,所以也就是式子的分配式推廣到各個子節點計算出來的和)。我們已經知道了各個節點到達根節點的距離和,那么從根節點開始遞推下來可以得到各個點的距離和。另開一個數組表示每個節點的到其他節點的距離和,那么對於根節點u來說, dissum[u] = dp[u]。以 u 的兒子 v 為例, v 的子節點到 v 不必經過 v->u 這條路徑,因此 dissum[u] 多了 nodesum[v] * 1,但是對於不是 v 的子節點的節點,只到達了 u ,因此要到達 v 必須多走 u->v 這條路徑,因此 dissum[u] 少了 ( N - nodesum[v] ) * 1) ,所以 dissum[v] = dissum[u] - nodesum[v] * 1 + (N - nodesum[v] ) * 1,按照這個方法遞推下去就可以得到各個點的距離和。

  

 1 class Solution {
 2     private int tot = 0;
 3     private Edge[] edge;
 4     private int[] head;
 5     private int[] dp;
 6     private int[] nodesum;
 7     private int[] dissum;
 8     public int[] sumOfDistancesInTree(int N, int[][] edges) {
 9         edge = new Edge[2 * N + 5];
10         head = new int[N + 5];
11         dp = new int[N + 5];
12         nodesum = new int[N  + 5];
13         dissum = new int[N];
14         Arrays.fill(head,-1);
15         for (int i = 0;i < edges.length;i++){
16             int u = edges[i][0];
17             int v = edges[i][1];
18             addedge(u,v);
19             addedge(v,u);
20         }
21         dfs1(0,0);
22         dissum[0] = dp[0];
23         dfs2(0,0,N);
24         return dissum;
25     }
26 
27     public void addedge(int u,int v){
28         edge[tot] = new Edge();
29         edge[tot].u = u;
30         edge[tot].v = v;
31         edge[tot].next = head[u];
32         head[u] = tot++;
33     }
34 
35     public void dfs1(int u,int fa){
36         dp[u] = 0;
37         nodesum[u] = 1;
38         for (int i = head[u];i != -1;i = edge[i].next){
39             int v = edge[i].v;
40             if (v == fa)    continue;
41             dfs1(v,u);
42             dp[u] += dp[v] + nodesum[v];
43             nodesum[u] += nodesum[v];
44         }
45     }
46 
47     public void dfs2(int u,int fa,int sum){
48         for (int i = head[u];i != -1;i = edge[i].next){
49             int v = edge[i].v;
50             if (v == fa)    continue;
51             dissum[v] = dissum[u] - nodesum[v] + sum - nodesum[v];
52             dfs2(v,u,sum);
53         }
54     }
55     class Edge{
56         int u,v,next;
57     }
58 }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM