104. 二叉树的最大深度

104. 二叉树的最大深度

难度简单1195收藏分享切换为英文接收动态反馈

给定一个二叉树,找出其最大深度。

二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。

说明: 叶子节点是指没有子节点的节点。

示例:
给定二叉树 [3,9,20,null,null,15,7]

    3
   / \
  9  20
    /  \
   15   7

返回它的最大深度 3 。

我的解题思路:

  声明两个全局变量,其中一个变量用来进行每次的深度累加计算,另一个变量用来存储最深的深度,每当检测到root是null之后,说明一次深度探测完毕,探测完毕之后i归0,将i和另一个变量进行比较,如果i更大,那么就会将i存放在那个变量中。仔细思考的话这个算法并不行得通,因此每次检测到null都会强制的归零,而深度优先遍历并不是每次都从根节点出发的,这就会导致部分路径计算错误,进而影响整体的准确性,实际上,压根不准。

官方解题思路:

  方法一:深度优先搜索

  如果知道了左子树和右子树的最大深度l和r,那么该二叉树的最大深度为:max(l,r)+1。

  而左子树和右子树的最大深度又可以以同样的方法进行计算,因此我们可以使用深度优先搜索的方式来计算二叉树的最大深度,在计算当前二叉树的深度时,可以先递归计算其左子树和右子树的最大深度,然后再O(1)时间内计算出当前二叉树的最大深度。这个道理我确实没有想到,没有想到使用递归的方式来这样逐步计算每棵子树的左右子树的深度,可能还是对于树这方面做题做的比较少,而且连代码我也没有什么思路

代码(转自LeetCode官方网站,仅供参考):

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

作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/solution/er-cha-shu-de-zui-da-shen-du-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  关于这里的代码非常值得深思,说白了还是一个递归思想,让每次递归都返回一个值,这个值是和上上一层的两个子树的遍历的返回相关的,实际上,这里还是我的认知落后了,对于在树种的递归,每次递归当相当于针对一颗以当前节点为根节点的树的处理,而每次返回自然而然就是这棵树的高度,在进行递归的时候,会首先调用至最下面的一层,然后遇到空之后便发生了返回,这时我们就能得到每个叶子结点的深度了,这个深度自然为1,然后再往上进行返回,同层的树因为其递归层数不同,因此返回到同层的时候,左右子树的深度也出现了差异,这时比较的意义就体现出来了。这里实际上是可以画一个堆栈图进行了解的。

image-20220413221443669

image-20220413221555762

image-20220413221628455

image-20220413221740724

image-20220413221803527

image-20220413221835274

image-20220413221922105

image-20220413222031845

image-20220413222100847

image-20220413222128215

image-20220413222209487

image-20220413222237513

image-20220413222254741

image-20220413222319158

image-20220413222342504

image-20220413222408545

  就是这些图片所指示的过程。

  方法二:广度优先遍历

  对于广度优先便利我确实有考虑,但是考虑的不深也没有作为首选项,现在我来看看官方解题。我们也可以使用广度优先算法的方法来解决这道题目,但是我们需要对其进行一些更改,此时广度优先搜索队列里存放的是当前层的所有节点,每次拓展下一层的时候,不同于广度优先搜索的每次只从队列里拿出一个节点,我们需要将队列中的所有节点都拿出来拓展,这样能保证每次拓展完的时候队列里存放的是当前层的所有节点,也就是说我们这样一层一层的进行拓展,我们的拓展次数就是二叉树的最大深度。关于这个算法我确实有考虑,但是我不知道如何判断哪一些节点属于哪一层,但是我现在经过思考我明白了在层序遍历中,我们实际上是完全可以知道哪一些节点属于哪一层的,这和一些复杂的标记没有关系,只和我们的访问方式有关系,或者说和我们入队出队的方式有关系,只要我们在每次入队完成之后,先一股脑的出队,先把队列清空,只要我们按照这个方式进行出队入队,从头开始就这么执行的话,那么我们就能够保证每次队列中的元素都属于同一层。比如:

image-20220413223221895

image-20220413223252499

image-20220413223323338

  上述图片表达的就是这个意思,就是我们先将根节点入队,然后将队列完全清空,然后我们这时候需要找一个东西暂存这些被清出去的队列,然后我们再根据这些被清出去的队列让它们的下一层入队,这样我们在每次进行拓展,队列中存放的都是同一层的队列元素,不会掺杂。这里我认为算是一个基础的认知,需要记住这种层序遍历的拓展方式,也就是逐层拓展的层序遍历访问方式。

代码(转自LeetCode官方网站,仅供参考):

class Solution {
    public int maxDepth(TreeNode root) {
        if (root == null) {
            return 0;
        }
        Queue<TreeNode> queue = new LinkedList<TreeNode>();
        queue.offer(root);
        int ans = 0;
        while (!queue.isEmpty()) {
            int size = queue.size();
            while (size > 0) {
                TreeNode node = queue.poll();
                if (node.left != null) {
                    queue.offer(node.left);
                }
                if (node.right != null) {
                    queue.offer(node.right);
                }
                size--;
            }
            ans++;
        }
        return ans;
    }
}

作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/solution/er-cha-shu-de-zui-da-shen-du-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  最后附上我自己的解决方法,我更加倾向于使用递归的那个方法,方法如下:

class Solution {
    public int maxDepth(TreeNode root) {
        if (root == null) {
            return 0;
        }
        int a = maxDepth(root.left);
        int b = maxDepth(root.right);
        if (a >= b) {
            return a + 1;
        }
        return b + 1;
    }
}


posted @ 2022-04-13 23:06  云杉木屋  阅读(15)  评论(0编辑  收藏  举报