博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
树中的路径和 Sum of Distances in Tree
阅读量:5051 次
发布时间:2019-06-12

本文共 2984 字,大约阅读时间需要 9 分钟。

2019-03-28 15:25:43

问题描述:

问题求解:

写过的最好的Hard题之一。

初看本题,很经典的路径和嘛,dfs一遍肯定可以得到某个节点到其他所有节点的距离和。这种算法的时间复杂度是O(n ^ 2)。看一下数据量,emmm,果然不行。这个数据量一看就知道只能是O(n)的算法了。

只遍历一遍最多只能得到一个解,因此本题肯定是需要遍历至少两遍的。

在第一遍遍历的时候我们需要保存下两个值,一个是当前节点的subtree的路径总和,一个是当前节点的subtree的总的节点数。

在第二遍遍历的时候,我们已经知道root节点的值已经是最终的结果了,这个时候当我们将根节点从root移动到其child的时候,有cnt[child]的节点数的离现在的根节点近了一步,有N - cnt[child]的节点到当前根节点远了一步,所以res[child] = res[root] - cnt[child] + N - cnt[child]。这样再次遍历所有节点更新res数组得到的结果就是我们需要的最终的答案。

public int[] sumOfDistancesInTree(int N, int[][] edges) {        List
> graph = new ArrayList<>(); int[] res = new int[N]; int[] cnt = new int[N]; for (int i = 0; i < N; i++) graph.add(new HashSet<>()); for (int[] edge : edges) { graph.get(edge[0]).add(edge[1]); graph.get(edge[1]).add(edge[0]); } dfs1(0, -1, res, cnt, graph); dfs2(0, -1, res, cnt, graph); return res; } private void dfs1(int root, int parent, int[] res, int[] cnt, List
> graph) { for (int node : graph.get(root)) { if (node == parent) continue; dfs1(node, root, res, cnt, graph); cnt[root] += cnt[node]; res[root] += res[node] + cnt[node]; } cnt[root] += 1; } private void dfs2(int root, int parent, int[] res, int[] cnt, List
> graph) { for (int node : graph.get(root)) { if (node == parent) continue; res[node] = res[root] - cnt[node] + cnt.length - cnt[node]; dfs2(node, root, res, cnt, graph); } }

 

2019-04-17 14:26:20

public int[] sumOfDistancesInTree(int N, int[][] edges) {        List
> graph = new ArrayList<>(); for (int i = 0; i < N; i++) graph.add(new HashSet<>()); for (int[] edge : edges) { graph.get(edge[0]).add(edge[1]); graph.get(edge[1]).add(edge[0]); } int[] res = new int[N]; int[] cnt = new int[N]; int[] used = new int[N]; used[0] = 1; dfs1(graph, 0, res, cnt, used); Arrays.fill(used, 0); used[0] = 1; dfs2(graph, 0, res, cnt, used); return res; } private int[] dfs1(List
> graph, int root, int[] res, int[] cnt, int[] used) { res[root] = 0; cnt[root] = 1; for (int node : graph.get(root)) { if (used[node] == 1) continue; used[node] = 1; int[] r = dfs1(graph, node, res, cnt, used); res[root] += r[0] + r[1]; cnt[root] += r[1]; } return new int[]{res[root], cnt[root]}; } private void dfs2(List
> graph, int root, int[] res, int[] cnt, int[] used) { for (int node : graph.get(root)) { if (used[node] == 1) continue; used[node] = 1; res[node] = res[root] + cnt[0] - cnt[node] * 2; dfs2(graph, node, res, cnt, used); } }

  

 

转载于:https://www.cnblogs.com/TIMHY/p/10615394.html

你可能感兴趣的文章
Inoodb 存储引擎
查看>>
数据结构之查找算法总结笔记
查看>>
Android TextView加上阴影效果
查看>>
Requests库的基本使用
查看>>
C#:System.Array简单使用
查看>>
「Foundation」集合
查看>>
二叉树的遍历 - 数据结构和算法46
查看>>
类模板 - C++快速入门45
查看>>
RijndaelManaged 加密
查看>>
Android 音量调节
查看>>
windows上面链接使用linux上面的docker daemon
查看>>
Redis事务
查看>>
Web框架和Django基础
查看>>
python中的逻辑操作符
查看>>
HDU 1548 A strange lift (Dijkstra)
查看>>
每天一个小程序—0005题(批量处理图片大小)
查看>>
JavaScript特效源码(3、菜单特效)
查看>>
Linux常用命令总结
查看>>
yii模型ar中备忘
查看>>
C#线程入门
查看>>