树中的路径和 Sum of Distances in Tree
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的更多相关文章
- 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 ...
- [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 ...
- [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 ...
- [LeetCode] 834. Sum of Distances in Tree
LeetCode刷题记录 传送门 Description An undirected, connected treewith N nodes labelled 0...N-1 and N-1 edge ...
- 【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 ...
- leetcode834 Sum of Distances in Tree
思路: 树形dp. 实现: class Solution { public: void dfs(int root, int p, vector<vector<int>>& ...
- [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 ...
- CodeChef Sum of distances(分治)
CodeChef Sum of distances(分治) 题目大意 有一排点,每个点 i 向 \(i + 1, i + 2, i + 3\) 分别连价值为 \(a_i,b_i,c_i\) 的有向边, ...
- 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 ...
随机推荐
- java的智能提示无法打开
第一步:选中“window”->“preference” 第二步:选中“java”,并展开 第三步:选中“Editor”,并展开 第四步:选中“Content Assist”,在右侧 ...
- java Design Patterns
设计模式(Design Patterns) ——可复用面向对象软件的基础 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了 ...
- Java课程02-动手动脑
1.编写一个方法,生成一千个随机数,纯随机数发生器. package random; public class random { public static void main(String[] ar ...
- PHP----------linux下安装opcache.
1.首先查看是否安装了opcache扩展,使用php -m 命令查看安装的扩展(没有添加环境变量就使用:/usr/local/php/bin/php -m). 添加opcache扩展.(我自己封装的s ...
- Elasticsearch.安装(单节点)
Elasticsearch.安装(单节点) 环境Linux 7.x jdk 1.8 elasticsearch 5.x 环境目录结构(根目录多了两个文件夹): /resources /** 存放 ...
- 梳理vue双向绑定的实现原理
Vue 采用数据劫持结合发布者-订阅者模式的方式来实现数据的响应式,通过Object.defineProperty来劫持数据的setter,getter,在数据变动时发布消息给订阅者,订阅者收到消息后 ...
- WCF 基础框架
WCF 基础框架: 1,契约:契约书一语个服务公共接口的一部分,一个服务的契约定义了服务端公开的方法,使用的传递协议,可访问的地址,传输的消息格式等内容,主要包括数据契约,消息契约,服务契约等. 2, ...
- nmon安装与使用
一.检查安装环境 1,# uname –a (查看操作系统信息,所检查服务器为64位操作系统) Linux jmeter 2.6.32-504.el6.x86_64 #1 SMP Wed Oct 15 ...
- 2017.11.19 C语言基础及流水灯实现
/* 从右往左*/ #include <reg52.h> sbit ADDR0 = P1^0; sbit ADDR1 = P1^1; sbit ADDR2 = P1^2; sbit ADD ...
- maven 安装m2e 报错
Eclipse安装maven插件m2e m2e - http://m2eclipse.sonatype.org/sites/m2e m2e-extras - http://m2eclipse.sona ...