Day17|110.平衡二叉树, 257. 二叉树的所有路径, 404.左叶子之和
110.平衡二叉树
思路
平衡二叉树,左右子树的高度差不超过1。
后序遍历,如果一个节点的左节点和右节点的高度差不超过1,则返回最深的节点高度,通过左右中的方式,将结果向上传递。
尝试写代码:
class Solution:
def isBalanced(self, root: Optional[TreeNode]) -> bool:
if not root:
return True # 不知道这里该写 True 还是 0
left_heighgt = self.isBalanced(root.left)
right_height = self.isBalanced(root.right)
if abs(left_heighgt - right_height) > 1:
return False
height = max(left_heighgt, right_height) + 1
return height
return True
结果不对。
不清楚返回值如何写。每次如果返回了节点的高度值,就无法返回判断结果(True or False)
根据代码随想录视频
要点:
- 如果判断节点的左右子树高度差超过1, 则返回‘-1’
- 每次得到左子树或者右子树的高度时,先判断该值是不是‘-1’,如果是,直接返回‘-1’
根据视频写代码:
class Solution:
def isBalanced(self, root: Optional[TreeNode]) -> bool:
if not root:
return 0
left_heighgt = self.isBalanced(root.left)
if left_heighgt == -1:
return -1
right_height = self.isBalanced(root.right)
if right_height == -1:
return -1
if abs(left_heighgt - right_height) > 1:
return -1
else:
height = max(left_heighgt, right_height) + 1
return height
结果依旧不对。返回值是某个具体的数字,而不是题目要求的True或者False。
注意
此时可以重新创建一个函数,将之前的所有操作放进新函数中,在本身判断是否是平衡二叉树的函数中调用该函数。
最终代码:
class Solution:
def isBalanced(self, root: Optional[TreeNode]) -> bool:
if self.getHeight(root) == -1:
return False
else:
return True
def getHeight(self, root):
if not root:
return 0
left_height = self.getHeight(root.left)
if left_height == -1:
return -1
right_height = self.getHeight(root.right)
if right_height == -1:
return -1
if abs(left_height - right_height) > 1:
return -1
else:
height = max(left_height, right_height) + 1
return height
257. 二叉树的所有路径
思路
没有思路,不知道如何写。
甚至不清楚应该用什么遍历顺序。
根据代码随想录视频
要点:
- 前序遍历,因为只有前序遍历,能让父节点指向孩子节点,输出最终的形式。
- 本题有回溯的过程
- 终止条件:如果节点的左右孩子都为空,则遍历到叶子节点,即收集到了一条完整的路径。
- 中左右,中代表处理过程。本题的“中”需要放在终止条件的上面,不然可能就return了
- 写到“左右”时,需要先判断是否存在左右节点
- 向左向右遍历后,写完递归,就要写回溯。这里的回溯,就是将之前push进来的节点再pop出去
尝试写代码
class Solution:
def binaryTreePaths(self, root: Optional[TreeNode]) -> List[str]:
path = []
result = []
return self.traversal(root, path, result)
def traversal(self, node, path, result):
# 中
path.append(str(node.val))
# 终止条件
if not node.left and not node.right:
result.append('->'.join(path))
# 左
if node.left:
self.traversal(node.left, path, result)
path.pop() # 回溯
# 右
if node.right:
self.traversal(node.right, path, result)
path.pop() # 回溯
return result
历经多次debug,终于成功通过!
注意:
回溯函数可以没有返回值,因为参数中已经有最终结果了。
最终代码:
class Solution:
def binaryTreePaths(self, root: Optional[TreeNode]) -> List[str]:
path = []
result = []
self.traversal(root, path, result)
return result
def traversal(self, node, path, result):
# 中
path.append(str(node.val))
# 终止条件
if not node.left and not node.right:
result.append('->'.join(path))
# 左
if node.left:
self.traversal(node.left, path, result)
path.pop() # 回溯
# 右
if node.right:
self.traversal(node.right, path, result)
path.pop() # 回溯
return
Python函数map
使用map()函数,可以直接将列表中的所有值,全部转换为str
a=(1,2,3,4,5)
la=map(str,a)
# 输出:
# ['1', '2', '3', '4', '5']
404.左叶子之和
思路
用中序遍历,遍历左叶子后,在“中”的处理逻辑中,将左叶子的值加起来
尝试写代码:
class Solution:
def sumOfLeftLeaves(self, root: Optional[TreeNode]) -> int:
result = []
self.traversal(root, result)
return sum(result)
def traversal(self, node, result):
if not node.left and not node.right:
return
if node.left:
self.traversal(node.left, result)
if node.left:
result.append(node.left.val)
if node.right:
self.traversal(node.right, result)
结果错误,因为题目要求求出左叶子节点的和,上面代码算的是所有左节点之和。
该思路有问题。
不太清楚,如何将 该节点是否是左叶子节点 的判断放在哪里?如果放在终止条件中,该如何判断?
根据代码随想录视频:
要点:
- 判断左叶子节点时,无法在该叶子节点上判断,只能在该叶子节点的父节点上判断,即一个节点存在左节点,且其左节点的左右孩子为空。
- 使用后序遍历容易,因为可以讲结果一层层返回。
利用该逻辑写代码:
class Solution:
def sumOfLeftLeaves(self, root: Optional[TreeNode]) -> int:
result = []
self.traversal(root, result)
return sum(result)
def traversal(self, node, result):
if node.left:
self.traversal(node.left, result)
if node.right:
self.traversal(node.right, result)
if node.left and not node.left.left and not node.left.right:
result.append(node.left.val)
return
成功通过!
只是这种写法,如果直接将每个左叶子的值加入result中,最后虽然值是对的,但返回之后,result又变为0了。
注意:
- 这道题不需要额外定义函数,只用题目给的主函数就够了。
最终代码:
class Solution:
def sumOfLeftLeaves(self, root):
if root is None:
return 0
if root.left is None and root.right is None:
return 0
leftValue = self.sumOfLeftLeaves(root.left) # 左
if root.left and not root.left.left and not root.left.right: # 左子树是左叶子的情况
leftValue = root.left.val
rightValue = self.sumOfLeftLeaves(root.right) # 右
sum_val = leftValue + rightValue # 中
return sum_val
总结:
需要重新写一遍代码