题目:
给定一颗二叉树,其中每个结点都含有一个数值。设计一个算法,打印结点数值总和等于某个给定值的所有路径。注意,路径不一定非得从二叉树的根节点或叶子节点开始或结束。
题目看起来似乎有点复杂,那么我们先简化一下,若路径从根节点开始,在任意节点结束。
于是就可以从根节点开始,向左向右访问子节点,计算每条路径上根节点到当前节点的数值和。若与给定的值相同变打印当前路径。
注意:
- 就算找到了总和,仍需要继续访问这条路径。
- 不必重复计算根节点到每个节点的和,可以用一个数据结构存储和。
那么从任意路径开始怎么办呢?可以把问题转化为“这个节点为某条路径的末端,这条路径的和为给定的数值”。
递归访问每个节点n时,将根节点到n的完整路径传入函数,再以相反的顺序将n到根节点的子路径的值加起来,等于给定的值时就打印路径。
public void findSum(TreeNode node, int sum){
int depth = depth(node);
int[] path = new int[depth];
findSum(node, sum, path, 0);
}
public void findSum(TreeNode node, int sum, int[] path, int level){
if(node == null){
return;
}
path[level] = node.data; //将当前节点插入路径
int pathSum = 0;
for(int i = level; i <= 0; i--){
pathSum += path[i];
if(pathSum == sum){
print(path, i, level);
}
}
findSum(node.left, sum, path, level + 1);
findSum(node.right, sum, path, level + 2);
path[level] = Integer.MIN_VALUE; //只是个编程习惯,将当前节点从路径中移除。其实下次会覆盖这个节点。
}
public int depth(TreeNode node){
if(node == null){
return 0;
}
return 1 + Math.max(depth(node.left), depth(node.right));
}
public void print(int[] path, int start, int end){
for(int i = start; i <= end; i++){
System.out.print(path[i] + " ");
}
System.out.println();
}
好了,如果题目再变一下:
有一棵二叉树,树上每个点标有权值,权值各不相同,请设计一个算法算出权值最大的叶节点到权值最小的叶节点的距离。二叉树每条边的距离为1,一个节点经过多少条边到达另一个节点为这两个节点之间的距离。
给定二叉树的根节点root,请返回所求距离。
先遍历全部树,记录下最小值和最大值的值和位置,再根据位置来算出距离。
public class Tree {
private int max=0; //记录最大值
private int min=99999; //记录最小值
private StringBuilder maxcodec; //记录最大值的记录 0表示向左边;1表示右边
private StringBuilder mincodec; //记录最小值的记录
void PreOrder(TreeNode T,char code,StringBuilder codec){
if(T!=null){
codec.append(code);
if(T.left==null && T.right==null)
{
if(max<T.val)
{
max=T.val;
maxcodec = codec;
}
if(min>T.val)
{
min=T.val;
mincodec = codec;
}
}
PreOrder(T.left,'0',new StringBuilder(codec));
PreOrder(T.right,'1',new StringBuilder(codec));
}
}
public int getDis(TreeNode root) {
PreOrder(root,'0',new StringBuilder());
int index=0;
int length = maxcodec.length()>mincodec.length()?maxcodec.length():mincodec.length();
for(index=0; index<length ;index++)
{
if(maxcodec.charAt(index)!=mincodec.charAt(index))
break;
}
return (maxcodec.substring(index).length()+mincodec.substring(index).length());
}