《剑指 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. 二叉树的深度(后序遍历、层序遍历,清晰图解)