问题描述:如果把二叉树看成一个图,父子节点之间的连线看成双向的,定义“距离”为两个节点之间边的个数。求二叉树中相距最远的两个节点的距离。
思路:相距最远的两个节点一定是叶子节点,且这两个叶子节点的路径有三种情况:
- 最大距离的两个节点都在左子树中(右图)
- 都在右子树中
- 最大路径经过根节点root(此时是左子树高度 与 右子树高度 之和 + 2)(左边的图)
图中红色连接线表示最长路径。
package suda.alex.chapter3;
public class LongestDisOfTree {
public static void main(String[] args) {
// TODO Auto-generated method stub
TreeNode node1 = new TreeNode(1);
TreeNode node2 = new TreeNode(2);
TreeNode node3 = new TreeNode(3);
node1.left = node2;
node2.right = node3;
Result result = findMaxDis(node1);
System.out.println(result.maxDis);
}
//设以节点x作为根节点的子树中,节点间的最大距离为dis(x)。
//三种情况:最大距离的两个节点都在左子树中、都在右子树中、经过根节点x(此时是左子树高度 与 右子树高度 之和)
//递推式:maxDis(x) = max{maxDis(x.left), maxDis(x.right), maxDep(x.left) + maxDep(x.right) + 2}
public static Result findMaxDis(TreeNode root) {
if(root == null){
return new Result(0, -1);
}
Result left = findMaxDis(root.left);
Result right = findMaxDis(root.right);
int maxDis = Math.max(Math.max(left.maxDis, right.maxDis), left.maxDep + right.maxDep + 2); //递推式
return new Result(maxDis, Math.max(left.maxDep, right.maxDep) + 1);
}
}
class Result{
int maxDis; //以节点x作为根节点的树中,节点间的最大距离 (maxDis(x))
int maxDep; //以root为根到叶子的最长距离 ( 其实是左子树高度 与 右子树高度的较大值 + 1)
public Result(int maxDis, int maxDep) {
super();
this.maxDis = maxDis;
this.maxDep = maxDep;
}
}
class TreeNode{
int val;
TreeNode left;
TreeNode right;
public TreeNode(int val) {
this.val = val;
}
}