《剑指 Offer》学习记录:题 55:二叉树的深度


本来我不是很想写这道题,但是看了 leetcode 的题解后觉得还是值得写的地方。

题 55:二叉树的深度

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

例如对于如图二叉树,二叉树的深度为 4。

二叉树结点定义为:

class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None

DFS

解题思路

这个是非常基本的操作,所以这种解法不是重点。利用分治的思想,想要得到整棵二叉树的深度,可以先求出左子树和右子树的深度,取二者中较深的深度加 1。对于倒数第二层的结点来说左子树和右子树的深度只能是为 0 或 1,当从最底层回溯到根结点时就可以得到二叉树的深度。

题解代码

class Solution:
    def maxDepth(self, root: TreeNode) -> int:
        if root == None:
            return 0
        else: 
            return max(self.maxDepth(root.left), self.maxDepth(root.right)) + 1

时空复杂度

由于需要 DFS 所有的结点,所以时间复杂度和空间复杂度都是 O(n)。

BFS

解题思路

使用层序遍历的方式,设置一个计数器,当遍历完一层时计数器加一,直到遍历完所有层返回计数器。关键在于如何判断何时遍历完一层,可以一次性将队列的元素都出队列,将队列中的结点的左子树和右子树全部入队列,这样就可以保证队列中只有某一层的结点了。当队列为空时,说明前一层就是二叉树最深的层次,就可以结束 BFS 了。

题解代码

class Solution:
    def maxDepth(self, root: TreeNode) -> int:
        if root == None:
            return 0

        que = [root]
        sum = 0
        while len(que) != 0:
            new_que = []
            for i in range(len(que)):
                if que[i].left != None:
                    new_que.append(que[i].left)
                if que[i].right != None:
                    new_que.append(que[i].right)
            sum = sum + 1
            que = new_que
        return sum

时空复杂度

由于需要 BFS 所有的结点,所以时间复杂度和空间复杂度都是 O(n)。但是由于 BFS 不需要回溯合并所有子问题,也不存在递归调用,因此无论时间还是空间上的开销会比 DFS 要小。

参考资料

《剑指 Offer(第2版)》,何海涛 著,电子工业出版社
面试题55 - I. 二叉树的深度(后序遍历、层序遍历,清晰图解)

posted @ 2021-07-26 15:05  乌漆WhiteMoon  阅读(95)  评论(0编辑  收藏  举报