二叉树的深度&平衡二叉树&二叉树的直径

二叉树的深度

输入一棵二叉树的根节点,求该树的深度。从根节点到叶节点依次经过的节点(含根、叶节点)形成树的一条路径,最长路径的长度为树的深度。

例如:

给定二叉树 `[3,9,20,null,null,15,7]`,
    3
   / \
  9  20
    /  \
   15   7
返回它的最大深度 3 

递归:

public int maxDepth(TreeNode root) {
    if(root==null){
        return 0;
    }
    return Math.max(maxDepth(root.left),maxDepth(root.right))+1;
}

层次遍历:

public int maxDepth(TreeNode root) {
    if(root==null){
        return 0;
    }
    Queue queue=new LinkedList<>();
    queue.offer(root);
    int dept=0;
    while(!queue.isEmpty()){
        //当前队列的大小即为这一层结点的个数
        int count=queue.size();
        //将这一层所有结点的孩子加入队列
        for (int i = 0; i 

二叉树的最小深度

给定一个二叉树,找出其最小深度。
最小深度是从根节点到最近叶子节点的最短路径上的节点数量。
说明:叶子节点是指没有子节点的节点。

示例 1:

输入:root = [3,9,20,null,null,15,7]
输出:2

层次
当遇到左右子树都为空的时候返回

public int minDepth(TreeNode root) {
    if (root == null) {
        return 0;
    }
    Queue queue = new LinkedList<>();
    queue.offer(root);
    int depth = 0;
    while (!queue.isEmpty()) {
        int count = queue.size();
        depth++;
        for (int i = 0; i < count; i++) {
            TreeNode node = queue.poll();
            if (node.left == null && node.right == null) {
                return depth;
            }
            if (node.left != null) {
                queue.offer(node.left);
            }
            if (node.right != null) {
                queue.offer(node.right);
            }
        }
    }
    return 0;
}

递归

public int minDepth(TreeNode root) {
    if (root == null) {
        return 0;
    }
    if (root.left == null && root.right == null) {
        return 1;
    }
    int min = Integer.MAX_VALUE;
    if (root.left != null) {
        min = Math.min(min, minDepth(root.left));
    }
    if (root.right != null) {
        min = Math.min(min, minDepth(root.right));
    }
    return min + 1;
}

N 叉树的最大深度

给定一个 N 叉树,找到其最大深度。
最大深度是指从根节点到最远叶子节点的最长路径上的节点总数。
N 叉树输入按层序遍历序列化表示,每组子节点由空值分隔(请参见示例)。

示例 1:

输入:root = [1,null,3,2,4,null,5,6]
输出:3

迭代

public int maxDepth(Node root) {
    if (root == null) {
        return 0;
    }
    Queue queue = new LinkedList<>();
    queue.offer(root);
    int depth = 0;
    while (!queue.isEmpty()) {
        int count = queue.size();
        for (int i = 0; i < count; i++) {
            root = queue.poll();
            for (Node node : root.children) {
                queue.add(node);
            }
        }
        depth++;
    }
    return depth;
}

递归

public int maxDepth(Node root) {
    if (root == null) {
        return 0;
    }
    int depth = 0;
    for (Node node : root.children) {
        depth = Math.max(depth, maxDepth(node));
    }
    return depth + 1;
}

平衡二叉树

输入一棵二叉树的根节点,判断该树是不是平衡二叉树。如果某二叉树中任意节点的左右子树的深度相差不超过1,那么它就是一棵平衡二叉树。

示例 1:

给定二叉树 [3,9,20,null,null,15,7]
  3
   / \
  9  20
    /  \
   15   7
返回 true

示例 2:

给定二叉树 [1,2,2,3,3,null,null,4,4]
      1
      / \
     2   2
    / \
   3   3
  / \
 4   4
返回 `false` 

限制:

  • 1 <= 树的结点个数 <= 10000

方法一:自顶向下

  • 判断当前子树是否平衡
  • 判断左子树是否平衡
  • 判断右子树是否平衡
    明显会存在重复计算
public boolean isBalanced(TreeNode root) {
    if (root == null) {
        return true;
    }
    return Math.abs(maxDepth(root.left) - maxDepth(root.right)) <= 1
        && isBalanced(root.left) && isBalanced(root.right);
}

public int maxDepth(TreeNode root) {
    if (root == null) {
        return 0;
    }
    return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1;
}

时间复杂度:O(nlogn)
isBalanced会遍历所有结点O(n),计算结点的深度O(logn)
空间复杂度:O(n)
如果树完全倾斜,递归栈可能包含所有节点

方法二:自底向上
先判断子树是否平衡(如果不平衡直接返回),再判断当前是否平衡

public boolean isBalanced(TreeNode root) {
    return depth(root) != -1;
}

public int depth(TreeNode root) {
    if (root == null) {
        return 0;
    }
    int leftDepth = depth(root.left);
    if (leftDepth == -1) {//不平衡,剪枝
        return -1;
    }
    int rightDepth = depth(root.right);
    if (rightDepth == -1) {
        return -1;
    }
    return Math.abs(leftDepth - rightDepth) <= 1 ?
        Math.max(leftDepth, rightDepth) + 1 : -1;
}

时间复杂度O(n)
空间复杂度O(n)

二叉树的直径

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

示例 :
给定二叉树

          1
         / \
        2   3
       / \     
      4   5    

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

相当于计算两个结点间的路径长度,最长的路径必定来自于叶子结点
两个叶子结点的路径等于两个结点的深度之和
相当于找到哪两个叶子结点的深度之后最大

private int maxDiameter;

public int diameterOfBinaryTree(TreeNode root) {
    depth(root);
    return maxDiameter;
}

public int depth(TreeNode root) {
    if (root == null) {
        return 0;
    }
    int leftDepth = depth(root.left);
    int rightDepth = depth(root.right);
    maxDiameter = Math.max(maxDiameter, leftDepth + rightDepth);
    return Math.max(leftDepth, rightDepth) + 1;
}

你可能感兴趣的:(二叉树的深度&平衡二叉树&二叉树的直径)