【HackerRank】Cut the tree
题目链接:Cut the tree
题解:题目要求求一条边,去掉这条边后得到的两棵树的节点和差的绝对值最小。
暴力求解会超时。
如果我们可以求出以每个节点为根的子树的节点之和,那么当我们去掉一条边(a,b)的时候,其中的一棵树必是以a或者b为根的子树,那么我们就可以知道生成的两棵树的节点之和了。所以,当我们得到以每个节点为根的子树节点和这个信息后(把这个信息存储在TreeNode的value变量中),通过遍历每个节点(每个节点为根的子树必然为某次cut得到的子树之一,例如下图中,2为根的子树对应切割边(1,2)得到的树,而5为根的子树对应切割边(1,5)得到的树),求出最小的W-2*root.value即为所求(W是所有节点的值得和)。

树节点的数据结构定义如下:
static class TreeNode{
int value;
int number;
ArrayList<TreeNode> children;
public TreeNode(int value,int number){
this.value = value;
this.number = number;
children = new ArrayList<TreeNode>();
}
}
value表示该顶点对应的值,number表示顶点的编号,children表示子节点的列表(这里指表示连接关系,也有可能children里面其实存放了父节点,不过可以用接下来的visited数组避免访问到父节点)。
然后从树的任意一个节点开始dfs,把它的value值依次加上各个child为root的子树节点值,就得到以它为root的子树的节点值得和了。而它的child为root的子树节点和就用递归的方法求。上面说了,每次读入一条边(a,b)的时候,即把b加入到a的children集合里面,也把a加入到b的children集合里面。那么在dfs的时候,怎么知道谁是父节点,谁是子节点呢?就用一个visited数组,因为在dfs过程中,父节点一定先被访问,所以在一个节点的children集合里面,已经被visited过的节点就不是它的子节点了。
最后代码如下:
import java.util.*;
public class Solution {
static class TreeNode{
int value;
int number;
ArrayList<TreeNode> children;
public TreeNode(int value,int number){
this.value = value;
this.number = number;
children = new ArrayList<TreeNode>();
}
}
private static int dfs(TreeNode root,boolean[] visited){
visited[root.number]=true;
for(TreeNode child:root.children){
if(!visited[child.number]){
root.value += dfs(child, visited);
}
}
return root.value;
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
TreeNode[] treeNodes = new TreeNode[n];
int W = 0;
for(int i = 0;i < n;i++)
{
int value = in.nextInt();
treeNodes[i]=new TreeNode(value,i);
W += value;
}
for(int i = 0;i < n-1;i++){
int a = in.nextInt();
int b = in.nextInt();
treeNodes[a-1].children.add(treeNodes[b-1]);
treeNodes[b-1].children.add(treeNodes[a-1]);
}
boolean[] visited = new boolean[n];
dfs(treeNodes[0], visited);
int miniDif = Integer.MAX_VALUE;
for(TreeNode t:treeNodes){
miniDif = Math.min(miniDif, Math.abs(W-2*t.value));
}
System.out.println(miniDif);
}
}
另外要积累的一点是java中nested class和inner class的区别,见stackoverflow上面的详细解答,所以上述代码中第4行要把TreeNode声明为nested class,否则它只能通过类Solution调用。
【HackerRank】Cut the tree的更多相关文章
- 【数据结构】B-Tree, B+Tree, B*树介绍 转
[数据结构]B-Tree, B+Tree, B*树介绍 [摘要] 最近在看Mysql的存储引擎中索引的优化,神马是索引,支持啥索引.全是浮云,目前Mysql的MyISAM和InnoDB都支持B-Tre ...
- 【题解】Cut the Sequence(贪心区间覆盖)
[题解]Cut the Sequence(贪心区间覆盖) POJ - 3017 题意: 给定一大堆线段,问用这些线段覆盖一个连续区间1-x的最小使用线段的数量. 题解 考虑一个这样的贪心: 先按照左端 ...
- 【LeetCode】199. Binary Tree Right Side View 解题报告(Python)
[LeetCode]199. Binary Tree Right Side View 解题报告(Python) 标签: LeetCode 题目地址:https://leetcode.com/probl ...
- 【数据结构】B-Tree, B+Tree, B*树介绍
[摘要] 最近在看Mysql的存储引擎中索引的优化,神马是索引,支持啥索引.全是浮云,目前Mysql的MyISAM和InnoDB都支持B-Tree索引,InnoDB还支持B+Tree索引,Memory ...
- 【LeetCode】Balanced Binary Tree 解题报告
[题目] Given a binary tree, determine if it is height-balanced. For this problem, a height-balanced bi ...
- 【LeetCode】145. Binary Tree Postorder Traversal
Difficulty: Hard More:[目录]LeetCode Java实现 Description https://leetcode.com/problems/binary-tree-pos ...
- 【HackerRank】Utopian tree
The Utopian tree goes through 2 cycles of growth every year. The first growth cycle of the tree occu ...
- 【BZOJ-4353】Play with tree 树链剖分
4353: Play with tree Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 31 Solved: 19[Submit][Status][ ...
- 【leetcode】Binary Search Tree Iterator(middle)
Implement an iterator over a binary search tree (BST). Your iterator will be initialized with the ro ...
随机推荐
- 【精】cookie、 sessionStorage 、localStorage之间的异同
1.cookie:存储在用户本地终端上的数据.有时也用cookies,指某些网站为了辨别用户身份,进行session跟踪而存储在本地终端上的数据,通常经过加密.一般应用最典型的案列就是判断注册用户是否 ...
- window linux IPC ftok BY_HANDLE_FILE_INFORMATION
看这题目就很乱,心情当然也是不怎么美好了.前一段时间做了一个项目,AIX(Unix的一种)中的一个系统向WINDOWS移植,开发环境由IBM的C/C++(叫什么忘记了,好像是xlC)变为VC++. 这 ...
- GoogleMap-------解决不能使用问题
前言:由于中国大部分Android手机中的Google服务都被阉割掉了,所以导致GoogleMap无法使用,可以用一下方法解决. 1.不能使用GoogleMap 2.若手机上装有安装市场之类的软件可搜 ...
- struts2之constant 讲解 (转)
struts.serve.static.browserCache 该属性设置浏览器是否缓存静态内容.当应用处于开发阶段时,我们希望每次请求都获得服务器的最新响应,则可设置该属性为false. stru ...
- libevent在windows下用visual studio编译时出现error C2894错误的原因与解决方法
libevent是一个使用很广泛的网络库,今天想了解下它.于是去git clone了一份源码,用vs2005的命令行:nmake -f makefile.nmake编译之,顺利编译通过,生成三个静态库 ...
- linux 文本编辑器
文本编辑器 文本编辑器是Linux操作系统中的重要工具.其中,VI是使用最广泛的文本编辑器,其可以在任何shell中使用.此外,Red Hat Enterprise Linux6 还提供了gedit工 ...
- PHP中导出Excel,将数据以Excel形式导出
现在,很多地方都需要导出数据,这里说一种简单的方法将数据以Excel的形式导出,方法如下: <?php date_default_timezone_set('PRC');//设置时区 /*设置h ...
- Invalid bound statement (not found) 问题处理
最近开发过程中遇到一个BUG:Invalid bound statement (not found): com.mapper.ResourceIdMappingsBatchMapper.deleteR ...
- 对 pthread 做的一个简陋封装
参考自 pthreadcc 库的 ThreadBase 类 用法:继承该类,重写 execute 方法,调用父类的 launchThread 方法启动线程 Thread.h // // Thread. ...
- Flow Problem(最大流模板)
Flow Problem Time Limit: 5000/5000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Tota ...