【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 ...
随机推荐
- spark集群模式
1.配置集群主机免登陆,参考http://www.cnblogs.com/puroc/p/5996730.html2.修改/etc/hosts文件,增加所有主机名和IP的对应关系 3.修改spark- ...
- linux上安装python3同时保留python2
linux上安装python3同时保留python2?这个就要用到上篇说到的path变量了. 具体介绍及操作 这里我下载python3.6版本来进行介绍 django默认数据库为sqlite3,所以安 ...
- python第四周迭代器生成器序列化面向过程递归
第一节装饰器复习和知识储备------------ 第一节装饰器复习和知识储备------------ def wrapper(*args,**kwargs): index(*args,**kwa ...
- servelet 直接输出内容
package helloworld; import java.io.IOException; import javax.servlet.ServletException; import javax. ...
- Hibernate通过many-to-one元素的一对一映射
在hibernate中我们可以通过两种方式来执行一对一映射: 通过many-to-one元素标签 通过one-to-one元素标签 在这里,我们将通过多对一的many-to-one元素进行一对一的映射 ...
- 浅谈javascript的this指向
This的指向大致能够分为下面四类.我们分别举例说明 1. 作为对象的方法调用时.this指向该对象 var obj={ a:1, getA:function(){ co ...
- TBSchedule源码阅读2-TBScheduleManagerFactory 定时任务ManagerFactoryTimerTask
定时任务 : 主要功能:监听zookeeper状态,正常则this.factory.refresh(),异常则this.factory.reStart(); 1 正常情况this.factory.re ...
- Unity3D学习笔记——NGUI之UIPopupList
UIPopupList:将这个组件添加到Button上,即可构建一个下拉列表. 效果图如下: 一:使用步骤 1.首先创建一个Sprite作为button. 2.创建一个label,用于显示当前选择的选 ...
- java输出
把一个java对象转化成一个json字符串: JSON.toJSON(user); JSON.toJSONStringWithDateFormat(user, "yyyy-MM-dd HH: ...
- 怎样利用JDBC启动Oracle 自己主动追踪(auto trace)
有时我们须要对运行SQL的详细运行过程做一个追踪分析,特别是在应用程序性能优化的时候.Oracle两个工具能够帮助我们做好性能分析,一个是SQL_TRACE,一个是SESSION_EVENT.SQL_ ...