给定一棵二叉树,你需要计算它的直径长度。一棵二叉树的直径长度是任意两个结点路径长度中的最大值。这条路径可能穿过也可能不穿过根结点。

    示例 :
    给定二叉树

    1. 1
    2. / \
    3. 2 3
    4. / \
    5. 4 5

    返回 3, 它的长度是路径 [4,2,1,3] 或者 [5,2,1,3]。

    注意:两结点之间的路径长度是以它们之间边的数目表示。

    分析:
    二叉树的直径可能过根节点也可能不过根节点
    过根节点的二叉树的直径:4-2-1-3 或 5-2-1-3

    1. 1
    2. / \
    3. 2 3
    4. / \
    5. 4 5

    不过根节点的二叉树的直径:7-5-4-2-0-8-1

    1. 9
    2. / \
    3. 3 2
    4. / \
    5. 4 0
    6. / /
    7. 5 8
    8. / /
    9. 7 1

    需要分别计算每棵子树的二叉树的直径,然后比较大小,取最大值
    每棵子树的二叉树的直径可以拆分为:左子树的最长边 + 右子树的最长边 + 2(根节点到左子树根节点 + 根节点到右子树根节点)
    而边又等于深度 - 1 ,深度 = 根节点到最远叶子节点的最长路径上的节点数
    比如根节点2的左子树 4 的深度是 3,边为 2 ,右子树 0 的深度是 3,边为 2,则根节点 2 的直径 = 2 + 2 + 2 = 3 + 3
    即二叉树的直径 = 左子树深度 + 右子树深度

    计算二叉树的深度:

    1. private int dept(TreeNode root) {
    2. if(root == null) {
    3. return 0;
    4. }
    5. int leftDept = dept(root.left);
    6. int rightDept = dept(root.right);
    7. return Math.max(leftDept, rightDept) + 1;
    8. }

    递归算法框架:

    1. public int diameterOfBinaryTree(TreeNode root) {
    2. dept(root);
    3. return ;
    4. }
    5. private int dept(TreeNode root) {
    6. if(root == null) {
    7. return 0;
    8. }
    9. int leftDept = dept(root.left);
    10. int rightDept = dept(root.right);
    11. int treeLenght = leftDept + rightDept;
    12. Math.max(maxTreeLength, treeLenght);
    13. return Math.max(leftDept, rightDept) + 1;
    14. }

    可以定义一个全局遍历,以用于在递归时比较:

    1. int maxTreeLength;
    2. public int diameterOfBinaryTree(TreeNode root) {
    3. maxTreeLength = Integer.valueOf(0);
    4. dept(root);
    5. return maxTreeLength;
    6. }
    7. private int dept(TreeNode root) {
    8. if(root == null) {
    9. return 0;
    10. }
    11. int leftDept = dept(root.left);
    12. int rightDept = dept(root.right);
    13. int treeLenght = leftDept + rightDept;
    14. maxTreeLength = Math.max(maxTreeLength, treeLenght);
    15. return Math.max(leftDept, rightDept) + 1;
    16. }