代码随想录算法训练营第十六天| 104. 二叉树的最大深度(递归写法)、111. 二叉树的最小深度(递归写法)、222. 完全二叉树的节点个数

173 阅读3分钟

104. 二叉树的最大深度

题目链接

leetcode.cn/problems/ma…

文章链接

programmercarl.com/0104.%E4%BA…

视频链接

www.bilibili.com/video/BV1Gd…

看到题目的第一想法

知道可以用递归来实现,但是不知道递归该怎么写。

看完代码随想录之后的想法

看了卡哥的视频才知道不仅有深度,还有高度的概念,在本题中深度和高度的值是一样的,不同之处在于参考点不同,如果最底层叶子结点为参考点,即为求高度。如果最上层根结点为参考点,即为求深度。这道题可以用前序遍历和后序遍历来实现,很多题解都是用的后序遍历,后序遍历其实求的是深度,其实和高度的值是一样的。根据“左右根”来求的。然后利用卡哥所讲的“递归三部曲”来实现递归的过程。下面附上我的go语言代码(后序遍历):

func maxDepth(root *TreeNode) int {
    if root == nil {
        return 0
    }
    left := maxDepth(root.Left) + 1
    right := maxDepth(root.Right) + 1
    return max(left, right)
}

func max(a, b int) int {
    if a > b {
        return a
    }
    return b
}

实现过程中遇到的困难

实现的过程中+1搞忘写了,导致结果始终为0,后来一想,递归的每一层都要加1,这样才能累加得到高度,也就是深度。

今日收获

看了卡哥的视频才知道原来这道题也隐藏了递归顺序,只是很多题解都没有写出来。

111. 二叉树的最小深度

题目链接

leetcode.cn/problems/mi…

文章链接

programmercarl.com/0111.%E4%BA…

视频链接

www.bilibili.com/video/BV1QD…

看到题目的第一想法

刚才那道题求的是最大深度,这道题求的是最小深度,最开始我以为就是把最大深度反过来就是最小深度,直到看了卡哥的视频,我才发现我想错了。

看完代码随想录之后的想法

卡哥在视频中说,这里的最小深度是叶子结点里面的最小深度,不是我之前理解的那个意思,举个例子,如果一颗二叉树左子树为空,右子树不为空,按照我之前的思路,那它的最小深度就是零,然而根据这道题的题意,最小深度不是零,是离根结点最近的叶子结点的深度。下面附上我的go语言代码:

func minDepth(root *TreeNode) int {
    if root == nil {
        return 0
    }
    left := minDepth(root.Left) + 1
    right := minDepth(root.Right) + 1
    if root.Left != nil && root.Right == nil {
        return left
    }
    if root.Left == nil && root.Right != nil {
        return right
    }
    return min(left, right)
}

func min(a, b int) int {
    if a < b {
        return a
    }
    return b
}

从代码中我们可以看到这道题是分情况讨论的,分为左子树为空,右子树不为空和左子树不为空,右子树为空这两种情况,分别返回不同的值。

实现过程中遇到的困难

基于上一道最大深度再来做这道题,就没什么难度了。

今日收获

这两道题均采用后序遍历来实现,中序遍历没法实现,前序遍历稍显复杂。

222. 完全二叉树的节点个数

题目链接

leetcode.cn/problems/co…

文章链接

programmercarl.com/0222.%E5%AE…

视频链接

www.bilibili.com/video/BV1eW…

看到题目的第一想法

第一想法也是想着用递归来实现,但是不知道完全二叉树怎么来判断。

看完代码随想录之后的想法

看完卡哥的视频后才恍然大悟,完全二叉树也是二叉树的一种,为什么不当成普通二叉树来求呢?所以按照卡哥的想法,我试着写了一下,下面是我的go语言代码:

func countNodes(root *TreeNode) int {
    if root == nil {
        return 0
    }
    result := 1
    result += countNodes(root.Left)
    result += countNodes(root.Right)
    return result
}

首先初始化result为1,根结点要算上,所以不可能是0,之后左子树和右子树累加,最后返回result,result即为结点个数。

实现过程中遇到的困难

实现过程并未遇到困难。

今日收获

此题也可以用完全二叉树的性质来求结点个数,但是实现过程的代码略显复杂,之后会进行补充。