Day16|104.二叉树的最大深度, 559.n叉树的最大深度, 111.二叉树的最小深度, 222.完全二叉树的节点个数
104.二叉树的最大深度
思路
尝试用递归,后序遍历
没有思路。
深度:二叉树中的节点到根节点的距离。
高度:与深度相反,二叉树中的节点到叶子节点的距离。
求高度,使用后序遍历,从下往上数。
求深度,使用前序遍历,中左右,往下遍历一个加一。
根据代码随想录视频
要点:
- 根节点的高度就是二叉树的最大深度,因此这道题可用后序遍历。
- “中”的处理逻辑为 左孩子和右孩子的最大值 + 1
- 如果node为None,此时的高度应该为0
最终代码:
class Solution:
def maxDepth(self, root: Optional[TreeNode]) -> int:
if not root:
return 0
left_height = self.maxDepth(root.left)
right_height = self.maxDepth(root.right)
height = 1 + max(left_height, right_height)
return height
559.n叉树的最大深度
思路
将每个子节点的高度都放入一个列表,传入他们的父节点时,取列表中最大的 + 1.
尝试写代码:
class Solution:
def maxDepth(self, root: 'Node') -> int:
if not root:
return 0
child_height = []
for child in root.children:
child_height.append(self.maxDepth(child))
height = 1 + max(child_height)
return height
倒数第二行出错。
因为不确定该字节点是否有值。
因此最好在每一个字节点返回时,直接加一,然后和最大值比较。
最终代码:
class Solution:
def maxDepth(self, root: 'Node') -> int:
if not root:
return 0
max_height = 1
for child in root.children:
max_height = max(max_height, self.maxDepth(child) + 1)
return max_height
111.二叉树的最小深度
思路
与最大深度一样,使用后序遍历,只不过使用最小值函数
但是,当只有一个字节点时,直接用min函数,结果错误。因此需要提前判断是否左右两个字节点都有值。
class Solution:
def minDepth(self, root: Optional[TreeNode]) -> int:
if not root:
return 0
left_height = self.minDepth(root.left)
right_height = self.minDepth(root.right)
if left_height and right_height:
height = 1 + min(left_height, right_height)
elif not left_height:
height = 1 + right_height
elif not right_height:
height = 1 + left_height
return height
成功通过!
根据代码随想录文章,可以判断的时候直接return
class Solution:
def minDepth(self, root: Optional[TreeNode]) -> int:
if not root:
return 0
left_height = self.minDepth(root.left)
right_height = self.minDepth(root.right)
if not root.left and root.right:
return 1 + right_height
elif not root.right and root.left:
return 1 + left_height
height = 1 + min(left_height, right_height)
return height
222.完全二叉树的节点个数
思路
可以用层序遍历。
也可以在求二叉树的深度的基础上计算节点个数,每层如果是满的,则有2^h个节点。
但是不确定,最后一层如果没有满,该如何计算节点。
用层序遍历求解:
class Solution:
def countNodes(self, root: Optional[TreeNode]) -> int:
if not root:
return 0
queue = deque([root])
result = 0
while queue:
level = len(queue)
for _ in range(len(queue)):
node = queue.popleft()
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
result += level
return result
成功通过!
根据代码随想录视频,既然这道题说了时完全二叉树,那就尽可能用完全二叉树的特性求解。
要点:
- 满二叉树的节点数量:
2^h - 1
,h为深度。 - 如果子树是满二叉树,那在知道子树的深度后,就可以求出当前节点的数量。
- 判断满二叉树的方法:节点一直向左遍历和一直向右遍历的深度是一样的。
- 终止条件:1) 节点为None,2) 满二叉树
普通二叉树的后序遍历解法:
class Solution:
def countNodes(self, root: Optional[TreeNode]) -> int:
if not root:
return 0
left_num = self.countNodes(root.left)
right_num = self.countNodes(root.right)
cur_num = left_num + right_num + 1
return cur_num
完全二叉树 后序遍历 解法:
class Solution:
def countNodes(self, root: Optional[TreeNode]) -> int:
if not root:
return 0
left = root.left
right = root.right
left_depth = 0
right_depth = 0
while left:
left = left.left
left_depth += 1
while right:
right = right.right
right_depth += 1
if left_depth == right_depth:
return 2 ** (left_depth + 1) - 1
left_num = self.countNodes(root.left)
right_num = self.countNodes(root.right)
return left_num + right_num + 1