LeetCode 104. Maximum Depth of Binary Tree

题目

Given a binary tree, find its maximum depth.The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node.

public class Solution104 {


    public static void main(String[] args) {
        Solution104 solution104 = new Solution104();

        TreeNode treeNode0 = new TreeNode(1);
        TreeNode treeNode1 = new TreeNode(1);
        TreeNode treeNode2 = new TreeNode(1);
        TreeNode treeNode3 = new TreeNode(1);
        TreeNode treeNode4 = new TreeNode(1);

        treeNode0.left  = treeNode1;
        treeNode0.right = treeNode2;
        treeNode2.left  = treeNode3;
        treeNode2.right = treeNode4;

        int depth = solution104.maxDepth(treeNode0);
        System.out.print(depth);
    }


    /**
     * 我的做法,用递归实现,但是线上提交显示超时.
     * 应该修改为注释的样子,用left,right保存
     */
    public int maxDepth(TreeNode root) {
        if(root==null){
            return 0;
        }


        if(1+maxDepth(root.left) > 1+maxDepth(root.right)){
            return  1+maxDepth(root.left);
        }else{
            return  1+maxDepth(root.right);
        }

//        int left = 1+maxDepth(root.left);
//        int right= 1+maxDepth(root.right);
//        if(left > right){
//            return  left;
//        }else{
//            return  right;
//        }


    }


}



class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode(int x) { val = x; }
}
<think>嗯,用户让我解释为什么这段代码叫做自底向上。让我先仔细看一下提供的代码。这是一个用C语言写的二叉树最大深度的递归解法。作者是灵茶山艾府,代码结构看起来挺典型的递归。 首先,我需要回忆一下二叉树遍历的两种常见方法:自顶向下和自底向上。自顶向下通常指的是在递归过程中,先处理当前节点,然后再递归处理子节点,比如前序遍历。而自底向上则是先递归到叶子节点,然后逐步返回处理,比如后序遍历。这个代码里的maxDepth函数,先递归调用左右子树,然后取最大值加1,明显是后序遍历的顺序,也就是先处理子节点再处理当前节点。所以这里可能就是因为这种后序的方式,导致被称为自底向上。 那问题来了,用户可能对递归的过程不太清楚,需要详细说明为什么递归的顺序决定了自底向上。比如,当函数递归到叶子节点的子节点(即NULL)时返回0,然后一步步返回到父节点,计算每个节点的深度。这个过程是从叶子节点开始,逐层向上计算深度,直到根节点。所以每个节点的深度都是基于其子节点的深度计算的,这符合自底向上的逻辑。 另外,用户可能混淆了自顶向下和自底向上的区别。例如,自顶向下可能在递归时传递当前的深度参数,比如在每一层递归中增加深度,直到叶子节点时比较最大值。而自底向上则是先得到子节点的深度,再计算当前节点的。所以这里的区别在于信息的传递方向:一个是向下传递参数,另一个是向上返回结果。 需要进一步解释代码的执行流程。比如,当root为NULL时返回0,否则递归计算左右子树的深度,取较大者加1。这个过程实际上是先深入到最底层(叶子节点的子节点),然后从那里开始返回深度值,逐层向上累加。因此,每个父节点的深度都依赖于子节点的结果,这种依赖关系导致了自底向上的计算方式。 可能用户的理解误区在于认为“自底向上”需要显式的从叶子节点开始处理,但递归的隐式栈实际上自动实现了这个过程。因为递归总是先处理最深的节点,然后回溯。所以虽然代码看起来像是从根节点开始,但实际的执行顺序是先到达底部,再逐步返回处理上层节点。 总结来说,这个递归方法被称为自底向上,是因为它先递归到叶子节点,然后从叶子节点开始计算深度,逐层返回到父节点,最终得到根节点的深度。这种方法利用递归栈的后序遍历特性,实现了从底层到顶层的深度计算。</think>这个递归解法被称为"自底向上"的原因,可以通过以下步骤理解: 1. **递归执行顺序** 代码采用的是后序遍历: $$ 左子树深度 \rightarrow 右子树深度 \rightarrow 当前节点深度 $$ 这保证了程序会先递归到二叉树的最底层(叶子节点),然后逐步向上计算每个父节点的深度。 2. **深度计算过程** 当遇到空节点时返回 0(递归终止条件),这相当于从树的最底层开始统计: $$\begin{aligned} 叶子节点深度 &= 1 \\ 父节点深度 &= max(左子树深度, 右子树深度) + 1 \\ 根节点深度 &= 最终结果 \end{aligned}$$ 3. **与自顶向下的对比** 如果是自顶向下方式,通常会通过参数传递当前深度,在递归过程中维护最大值。而本解法是通过子问题的解(子树深度)来构造原问题(整树深度)的解,这正是动态规划思想中的最优子结构特性。 4. **递归展开示例** 以简单二叉树 [3,9,20] 为例: ``` 3 ← 最后计算深度=3 / \ 9 20 ← 先计算这两个节点的深度=1 ``` 实际计算顺序是:9→20→3,完美体现了从底层向上传递计算结果的特征。 这种自底向上的递归方式时间复杂度为 $O(n)$(每个节点访问一次),空间复杂度为 $O(h)$(递归栈深度,h为树高)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值