力扣题库111,计算一个二叉树的最小深度。
题目链接点这里。
题目描述
给定一个二叉树,找出其最小深度。
最小深度是从根节点到最近叶子节点的最短路径上的节点数量。
说明: 叶子节点是指没有子节点的节点。
示例:
给定二叉树 [3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
返回它的最小深度 2.
解题思路
本题思路比较简单,利用DFS,迭代从下至上深度依次加1即可。
要注意的是类似于题目110,为了提升效率,当某一层一支出现叶子节点的时候即使该节点另外一支还可以继续往下也不需要再计算,可以提前进行阻断返回。
初始答案
按照上述思路答案如下
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def minDepth(self, root: TreeNode) -> int:
def isLeaf(node: TreeNode) -> bool:
if not node.left and not node.right:
return True
else:
return False
if not root:
return 0
elif isLeaf(root):
return 1
elif root.left and isLeaf(root.left) or root.right and isLeaf(root.right):
return 2
else:
leftDepth = self.minDepth(root.left)
rightDepth = self.minDepth(root.right)
if leftDepth == 0:
return rightDepth + 1
elif rightDepth == 0:
return leftDepth + 1
else:
return min(leftDepth,rightDepth) + 1
这里定义了一个判断叶子节点的临时函数isLeaf()
。
主要的难点就是需要考虑的特殊情况比较多:
首先如果传递的root不存在,返回0;
如果传递的root存在且为叶节点时返回1;
如果左右子节点有至少一个叶子节点时,就不再继续往下计算,直接返回2;因为isLeaf()
中没有判断root是否存在,所以这里要额外进行一次判断。
python中的逻辑运算顺序为not>and>or
最后是左右子节点至少存在一个并且不是叶子节点的情况,如果只有一个子节点,沿着该子节点往下计算,如果两个子节点都存在,两个都计算并用更小的深度加上1进行返回。
因为多种情况没有考虑完全,所以提交了很多次。不过因为进行了提前阻断返回,所以虽然最坏时候的时间复杂度为O(N),但实际表现是很好的,执行用时52ms,击败了88%的提交。
改进答案
官方答案还给出了基于BFS的计算思路。
DFS处理思路是递归,而BFS的处理思路是基于临时队列。放入队列的时候,除了放节点元素,还要将节点元素对应的深度也一起放进去,当队列中第一次出现叶子节点时直接返回深度即可。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def minDepth(self, root: TreeNode) -> int:
temp = []
if not root:
return 0
else:
temp.append((root,1))
while temp:
node,depth = temp.pop(0)
if not node.left and not node.right:
return depth
if node.left:
temp.append((node.left,depth+1))
if node.right:
temp.append((node.right,depth+1))
确实比DFS的代码要简洁,思路也更简单易懂一点。
因为也是在第一时间进行提前返回,所以虽然时间复杂度也是O(N),该提交和DFS一样也是击败了88%的提交。
注意事项
进行了多次提交主要是因为DFS的多种条件考虑不严谨导致,同时像这种从上至下计算并且可以提前返回的情况用BFS会更好一点。
我是T型人小付,一位坚持终身学习的互联网从业者。喜欢我的博客欢迎在csdn上关注我,如果有问题欢迎在底下的评论区交流,谢谢。