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 = ;
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[ * N + ];
10 head = new int[N + ];
11 dp = new int[N + ];
12 nodesum = new int[N + ];
13 dissum = new int[N];
14 Arrays.fill(head,-);
15 for (int i = ;i < edges.length;i++){
16 int u = edges[i][];
17 int v = edges[i][];
18 addedge(u,v);
19 addedge(v,u);
20 }
21 dfs1(,);
22 dissum[] = dp[];
23 dfs2(,,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] = ;
37 nodesum[u] = ;
38 for (int i = head[u];i != -;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 != -;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 }

最新文章

  1. wParam和lParam两个参数到底是什么意思?
  2. 1-File类的使用
  3. hdu1050 Moving Tables
  4. JS继承的几种方式
  5. 从零开始PHP学习 - 第二天
  6. 基于Visual C++2013拆解世界五百强面试题--题11-查找数字出现次数
  7. android代码实现关机
  8. Python一维数据分析
  9. Spark MLlib FPGrowth关联规则算法
  10. qt 拖拽 修改大小
  11. KMP初步
  12. mysql循环插入千万级数据
  13. C# 之 向服务器上传资源
  14. iiiLab提供的视频解析接口如何使用?转发个简单的使用教程
  15. cmake 常用变量和常用环境变量查表手册---整理 .
  16. 分析:java.lang.OutOfMemoryError: Java heap space
  17. python 相关模块安装 国内镜像地址
  18. 集合类List、Set、Map的区别、联系和遍历方式
  19. dva subscription的使用方法
  20. Django实现支付宝支付(沙箱)

热门文章

  1. SpringBoot2 Filter执行两次问题解决
  2. MySQL常见的三种存储引擎
  3. Spring Boot日志处理
  4. A1065
  5. 你肯定不知道的oracle数据库和sql server的这些区别
  6. POJ 3280 Cheapest Palindrome ( 区间DP &amp;&amp; 经典模型 )
  7. Java——常用类(File)
  8. [USACO10HOL]牛的政治Cow Politics
  9. Laya 首日红点逻辑
  10. Internet History, Technology, and Security(week1)——History: Dawn of Electronic Computing