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<Set<Integer>> 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<Set<Integer>> 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<Set<Integer>> 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<Set<Integer>> 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<Set<Integer>> 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<Set<Integer>> 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);
}
}

  

树中的路径和 Sum of Distances in Tree的更多相关文章

  1. 834. Sum of Distances in Tree —— weekly contest 84

    Sum of Distances in Tree An undirected, connected tree with N nodes labelled 0...N-1 and N-1 edges a ...

  2. [Swift]LeetCode834. 树中距离之和 | Sum of Distances in Tree

    An undirected, connected tree with N nodes labelled 0...N-1 and N-1 edges are given. The ith edge co ...

  3. [LeetCode] 834. Sum of Distances in Tree 树中距离之和

    An undirected, connected tree with N nodes labelled 0...N-1 and N-1 edges are given. The ith edge co ...

  4. [LeetCode] 834. Sum of Distances in Tree

    LeetCode刷题记录 传送门 Description An undirected, connected treewith N nodes labelled 0...N-1 and N-1 edge ...

  5. 【leetcode】834. Sum of Distances in Tree(图算法)

    There is an undirected connected tree with n nodes labeled from 0 to n - 1 and n - 1 edges. You are ...

  6. leetcode834 Sum of Distances in Tree

    思路: 树形dp. 实现: class Solution { public: void dfs(int root, int p, vector<vector<int>>& ...

  7. [LeetCode] 112. Path Sum ☆(二叉树是否有一条路径的sum等于给定的数)

    Path Sum leetcode java 描述 Given a binary tree and a sum, determine if the tree has a root-to-leaf pa ...

  8. CodeChef Sum of distances(分治)

    CodeChef Sum of distances(分治) 题目大意 有一排点,每个点 i 向 \(i + 1, i + 2, i + 3\) 分别连价值为 \(a_i,b_i,c_i\) 的有向边, ...

  9. Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all the values along the path equals the given sum. For example: Given the below binary tree andsum =

    Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all ...

随机推荐

  1. cocos creator使用anysdk接入admob广告教程

    http://lolling787.lofter.com/post/1f5b6553_12925042 cocos creator使用anysdk接入admob广告

  2. 把玩Pencil项目之编译并运行

    Pencil是个好项目.使用Electron作为运行环境,如同Vs Code一样,将JS跨平台桌面应用做了一个好的示范.个人很喜欢这种方式,毕竟多年来关注Web全栈开发,有一种JS一统天下的感觉.我的 ...

  3. Asp.net Image控件显示Bitmap生成图像

    from:https://blog.csdn.net/qq_29011299/article/details/81137980 using(Bitmap bmp=new Bitmap(300,50)) ...

  4. PHP 程序员危机(转载)

    感谢有这样的机会,能和大家一起来聊聊开发者的那些事儿. 其实程序员危机是一个真实存在的问题.也有人说是互联网行业的下滑或者互联网行业已过了风口等等.我在这儿主要谈的是 PHP 程序员的危机,而这种危机 ...

  5. DotNetty网络通信框架学习之源码分析

    DotNetty网络通信框架学习之源码分析 有关DotNetty框架,网上的详细资料不是很多,有不多的几个博友做了简单的介绍,也没有做深入的探究,我也根据源码中提供的demo做一下记录,方便后期查阅. ...

  6. echart的x换行

    option = { legend: { y: 'bottom', data:['该业务正常类比例','该业务关注类比例','该业务不良类比例'] }, xAxis: { type: 'categor ...

  7. WdatePicker 日期区间设置

    <input id="billsStartDate" name="billsStartDate" onclick="WdatePicker({d ...

  8. UWP中MarkupExtension的使用

    Xaml作为一种描述语言,在编程中极大地简化了页面开发的繁琐及时间消耗,这得益于它的多种特性:数据绑定.动画.资源文件等等.标记扩展作为其一个特性,在xaml中有不可替代的作用,今天分析下自定义标记扩 ...

  9. Gatling实战(二)

    在上一篇实战讲解了Gatling的用例,不过还没涉及到性能方面的内容,其实用例中的最后一句就和性能有关了 setUp(scn.inject(atOnceUsers(1)).protocols(http ...

  10. 【题解】Luogu P4069 [SDOI2016]游戏

    原题传送门 看到这种题,想都不用想,先写一个树链剖分 然后发现修改操作增加的是等差数列,这使我们想到了李超线段树 先进性树剖,然后用李超线段树维护区间最小,这样就做完了(写码很容易出错) 复杂度为\( ...