代码随想录算法训练营第十六天| LeetCode104.二叉树的最大深度、LeetCod559.n叉树的最大深度、LeetCode111.二叉树的最小深度、LeetCode222.完全二叉树的节点个数

#LeetCode 104. Maximum Depth of Binary Tree

#LeetCode 104. 视频讲解:二叉树的高度和深度有啥区别?究竟用什么遍历顺序?很多录友搞不懂 | LeetCode:104.二叉树的最大深度_哔哩哔哩_bilibili

深度:根节点到该节点的节点数,主要用前序遍历。

高度:该节点到叶子节点的节点数,主要用后序遍历。

本题中的最大深度,即为二叉树的高度,所以选择使用后序遍历。

在这个过程中没有单独设置一个变量来记录层数,而是使用遍历到末端节点后逐次加一得到的。

后序遍历方法:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public int maxDepth(TreeNode root) {
        if (root == null) {
            return 0;
        }
        int leftDepth = maxDepth(root.left);
        int rightDepth = maxDepth(root.right);
        return Math.max(leftDepth, rightDepth) + 1;
    }
}

#LeetCode 559. Maximum Depth of N-ary Tree

#LeetCode 559. 文字讲解:​​​​​​​代码随想录

观察节点的定义发现,子节点是通过一个List 接口来记录的,所以需要遍历所有的节点来比较哪一个节点的深度最大。我们此时需要一个depth 变量来记录层数。通过for 循环来遍历不同的子节点,此时对比的是depth (目前的最大层数)与目前遍历的child 层数。

后序遍历方法:

/*
// Definition for a Node.
class Node {
    public int val;
    public List<Node> children;

    public Node() {}

    public Node(int _val) {
        val = _val;
    }

    public Node(int _val, List<Node> _children) {
        val = _val;
        children = _children;
    }
};
*/

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

#LeetCode 111. Minimum Depth of Binary Tree

#LeetCode 111. 视频讲解:看起来好像做过,一写就错! | LeetCode:111.二叉树的最小深度_哔哩哔哩_bilibili

最小深度中需要注意的问题是根节点到叶节点的最小深度,而叶节点指的是左右孩子都为空的节点。所以,一颗没有左孩子的二叉树的深度应该看右子树的最小深度。依然是考虑用后序遍历来求最小高度,转化为深度。

递归三部曲:

确定递归函数的参数和返回值:参数为根节点,返回值为integer。

确定终止条件:如果root 节点为空。

确定单层递归的逻辑:按照后序遍历左右中的顺序遍历,在选择左右子树最小值时需要多考虑一下,是否存在左子树或者右子树为空,但是另一个子树非空的情况。

后序遍历方法:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public int minDepth(TreeNode root) {
        if (root == null) {
            return 0;
        }
        int result = 0;
        int leftHeight = minDepth(root.left);
        int rightHeight = minDepth(root.right);
        if (root.left == null && root.right != null) {
            return rightHeight + 1;
        }
        if (root.left != null && root.right == null) {
            return leftHeight + 1;
        }
        
        result = Math.min(leftHeight, rightHeight) + 1;
        
        return result;
    }
}

#LeetCode 222. Count Complete Tree Nodes

#LeetCode 222. 视频讲解:要理解普通二叉树和完全二叉树的区别! | LeetCode:222.完全二叉树节点的数量_哔哩哔哩_bilibili

如果是使用递归方法,则是普通的计数方法。在这个题目中还可以考虑使用完全二叉树的特性,来完成。如果一棵树是满二叉树(满二叉树一定是完全二叉树),那么它的节点数是2^{n} - 1,其中n 代表的是层数。在完全二叉树中一般有两种情况,如果不是满二叉树,那么则为最后一层没满。如果是满二叉树,则可以用公式来求解,如果是最后一层没有满,那么考虑递归,递归到某一个深度后一定有左孩子或者右孩子为满二叉树,然后再用满二叉树的特性。

递归方法:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public int countNodes(TreeNode root) {
        // recursion
        if (root == null) {
            return 0;
        }
        int leftCount = countNodes(root.left);
        int rightCount = countNodes(root.right);
        int result = leftCount + rightCount + 1;
        return result;
    }
}

利用二叉树的特性方法:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public int countNodes(TreeNode root) {
        if (root == null) {
            return 0;
        }
        TreeNode left = root.left;
        TreeNode right = root.right;
        int leftDepth = 0;
        int rightDepth = 0;
        while (left != null) {
            left = left.left;
            leftDepth++;
        }
        while (right != null) {
            right = right.right;
            rightDepth++;
        }
        if (leftDepth == rightDepth) {
            return (2 << leftDepth) - 1;
        }
        return countNodes(root.left) + countNodes(root.right) + 1;
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值