树中的路径和 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 ...
随机推荐
- linux 消息队列
消息队列,这个可是鼎鼎大名,经常在某些地方看见大家那个膜拜,那个,嗯,那个... 那就给个完整的例子,大家欣赏就行,我一直认为不用那个,嗯@ 这个队列的最大作用就是进程间通信,你要非搞个持久化,那也行 ...
- Oracle sql function LISTAGG
select business_unit, voucher_id, listagg( vat_txn_type_cd, ',') within group (order by business_uni ...
- 安装linux虚拟机
虚拟机安装流程 1. 安装系统 安装完成 2. 安装VMware tools linux(ubuntu 18.04 Desktop) 手动安装 1) 加载光驱 2) 双击进入光驱,在光驱的目录下,打开 ...
- SSH整合时多表关联查询出现Javassist增强失败
Customer类对应的表为另一个表LinkMan的外键,在进行LinkMan表操作时,出现如下错误. 遇到Javassist增强失败网上说法不一,有的说Customer没有无参构造方法,javass ...
- SQL死锁操作
这两天数据库经常被锁,所以记录一下操作: 查看被锁表:select request_session_id spid,OBJECT_NAME(resource_associated_entity_id) ...
- vscode小程序代码高亮
vscode无法识别wxml,wxss语法: wxml文件设置: (1)任意打开一wxml文件,点击下方语言模式选择,这里已关联wxm所以当前显示wxml.默认关联为纯文本或者html或其他语法,点击 ...
- android 开发设计模式---观察者模式
情景1 有一种短信服务,比如天气预报服务,一旦你订阅该服务,你只需按月付费,付完费后,每天一旦有天气信息更新,它就会及时向你发送最新的天气信息. 情景2 杂志的订阅,你只需向邮局订阅杂志,缴纳一定的费 ...
- cookiejar
referer:https://www.cnblogs.com/why957/p/9297779.html文章介绍了四种模拟登陆方法 yield Request()可以将一个新的请求返回给爬虫执行 在 ...
- Git 教程(三):仓库与分支
远程仓库 到目前为止,我们已经掌握了如何在Git仓库里对一个文件进行时光穿梭,你再也不用担心文件备份或者丢失的问题了. 可是有用过集中式版本控制系统SVN的童鞋会站出来说,这些功能在SVN里早就有了, ...
- CLASS 类 __getattr__
class Chain(object): def __init__(self, path=''): self._path = path def __getattr__(self, path): ret ...