给定一棵二叉树,你需要计算它的直径长度。一棵二叉树的直径长度是任意两个结点路径长度中的最大值。这条路径可能穿过也可能不穿过根结点。
示例 :
给定二叉树
1
/ \
2 3
/ \
4 5
返回 3, 它的长度是路径 [4,2,1,3] 或者 [5,2,1,3]。
注意:两结点之间的路径长度是以它们之间边的数目表示。
分析:
二叉树的直径可能过根节点也可能不过根节点
过根节点的二叉树的直径:4-2-1-3 或 5-2-1-3
1
/ \
2 3
/ \
4 5
不过根节点的二叉树的直径:7-5-4-2-0-8-1
9
/ \
3 2
/ \
4 0
/ /
5 8
/ /
7 1
需要分别计算每棵子树的二叉树的直径,然后比较大小,取最大值
每棵子树的二叉树的直径可以拆分为:左子树的最长边 + 右子树的最长边 + 2(根节点到左子树根节点 + 根节点到右子树根节点)
而边又等于深度 - 1 ,深度 = 根节点到最远叶子节点的最长路径上的节点数
比如根节点2的左子树 4 的深度是 3,边为 2 ,右子树 0 的深度是 3,边为 2,则根节点 2 的直径 = 2 + 2 + 2 = 3 + 3
即二叉树的直径 = 左子树深度 + 右子树深度
计算二叉树的深度:
private int dept(TreeNode root) {
if(root == null) {
return 0;
}
int leftDept = dept(root.left);
int rightDept = dept(root.right);
return Math.max(leftDept, rightDept) + 1;
}
递归算法框架:
public int diameterOfBinaryTree(TreeNode root) {
dept(root);
return ;
}
private int dept(TreeNode root) {
if(root == null) {
return 0;
}
int leftDept = dept(root.left);
int rightDept = dept(root.right);
int treeLenght = leftDept + rightDept;
Math.max(maxTreeLength, treeLenght);
return Math.max(leftDept, rightDept) + 1;
}
可以定义一个全局遍历,以用于在递归时比较:
int maxTreeLength;
public int diameterOfBinaryTree(TreeNode root) {
maxTreeLength = Integer.valueOf(0);
dept(root);
return maxTreeLength;
}
private int dept(TreeNode root) {
if(root == null) {
return 0;
}
int leftDept = dept(root.left);
int rightDept = dept(root.right);
int treeLenght = leftDept + rightDept;
maxTreeLength = Math.max(maxTreeLength, treeLenght);
return Math.max(leftDept, rightDept) + 1;
}