转自:https://blog.csdn.net/u012813201/article/details/75235625
从二叉树的节点A出发,可以向上或者向下走,但沿途的节点只能经过一次,当到达节点B时,路径上的节点数叫作A到B的距离。对于给定的一棵二叉树,求整棵树上节点间的最大距离。给定一个二叉树的头结点root,请返回最大距离。保证点数大于等于2小于等于500.
思路:
理解题目的含义,对于一棵以root为根的二叉树,树上的最大距离可能来自3中情况:
情况1:完全来自root的左子树,如图所示,即最大路径不经过root结点,只在结点1的左子树2上面,此时的最大距离为8。
情况2:完全来自root结点的右子树,如图所示,最大路径不经过root结点,只在结点1的右侧左子树3上面,此时最大距离是9。
情况3:来自结点root的两侧,如图所示,经过root结点,此时的最大距离=root的左子树的高度(即结点3的最长路径)+root右子树的高度(即结点3的最长路径)+root结点本身。
分析可知,要计算结点root所在子树的最长距离,需要已知:左子树②的最长距离LMaxLength,左子树的高度LHeight;右子树③的最长距离RMaxLength,右子树的高度RHeight.然后max(LMax,RMax,(LHeight+RHeight+1)),其最大值就是这棵二叉树的最大距离,即对于每个子树,需要求出它的最大距离和最大高度。
显然这就是一个递推关系式,可以使用递归来实现,即设计一个递归函数,给定一个根结点root,求出最大距离max和最大高度height并返回这2个数值。其中maxLength= Math.max(LMax,RMax,(LHeight+RHeight+1));而由于要返回这棵子树的高度,如何求子树的高度呢?二叉树的高度就是它的2个子树高度中的较大值再加上1,即height=Math.max(LHeight, RHeight)+1;
递归的递推关系有了,关键是找到递归的起始条件或者理解为终止条件。这里使用的思想是后序遍历(先遍历左右子树再处理结论),联系二叉树的后序遍历算法,进行改编。显然if(root==null)时:max=0;height=0;
总结:设计一个递归函数,输入根结点root,求出这棵二叉树的最大距离maxLength和高度length并返回。递推关系为:
maxLength= Math.max(LMax,RMax,(LHeight+RHeight+1));
height=Math.max(LHeight, RHeight)+1
边界条件为:
if(root==null) return max=0;height=0;
在Java中不能分开返回2个值,因此要将2个值整合成为一个数组进行返回即可
public class LongestDistance {
public int findLongest(TreeNode root) {
// write code here
int[] lenAndHei=get(root);
return lenAndHei[0];
}
public int[] get(TreeNode root){//递归求根为root的最大距离和高度
int[] lenAndHei=new int[2];
if(root==null){
lenAndHei[0]=lenAndHei[1]=0;
return lenAndHei;
}
//左子树的最大距离和高度
int[] left=get(root.left);
int leftLen=left[0];
int leftHei=left[1];
//右子树的最大距离和高度
int[] right=get(root.right);
int rightLen=right[0];
int rightHei=right[1];
//当前树的最大距离和高度
lenAndHei[0]=Math.max((Math.max(leftLen,rightLen)),(leftHei+rightHei+1));
lenAndHei[1]=Math.max(leftHei,rightHei)+1;
return lenAndHei;
}
}