110.平衡二叉树
1.第一想法
使用递归, 每一个递归:
- 终止条件:如果当前root为空,则终止,并返回当前位置的深度(不应当算这个空root)。
- 单层递归逻辑:先获得左子树的深度,再返回右子树的深度,比较两个深度的差,超过1则直接false,未超过1则返回
max(left_depth, right_depth)+1。 - 传入参数:上一层的深度,当前root节点。
- 返回值:当前树的深度,当前树是否为平衡二叉树。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def post(self, root):
if root is None:
return 0, True
else:
left_depth, is_balance_left = self.post(root.left)
right_depth, is_balance_right = self.post(root.right)
if abs(left_depth - right_depth) <= 1 and is_balance_left and is_balance_right:
is_balance = True
else:
is_balance = False
return max(left_depth, right_depth) + 1, is_balance
def isBalanced(self, root: Optional[TreeNode]) -> bool:
if root is None:
return True
else:
left_depth, left_balance = self.post(root.left)
right_depth, right_balance = self.post(root.right)
if abs(left_depth - right_depth) <= 1 and left_balance and right_balance:
return True
else:
return False
2.看完文档
文档链接
文档中没有外加任何is_balance的返回信号,而是用depth=-1表示不平衡,节省了空间,而且更加方便。
3. 学习时长
24分钟。
257. 二叉树的所有路径
1.第一想法
深度优先遍历,前序遍历,为啥是前序遍历呢?因为我们要再进入叶子节点前,先将叶子节点的parent节点放进遍历记录表中,当到达叶子节点的时候,就将当前遍历记录表加入到路径记录表中作为一条路径。 其次,当从左子树递归回来后,要把遍历记录表中的左孩子删掉,以恢复当前层节点为尾元素的遍历记录表,这样就恢复了原来的环境。 终止条件:当root没有左右孩子时就返回,返回前需要把自己加入到遍历记录表中,并将当前遍历记录表加入到路径记录表中作为一条路径。 本层递归操作逻辑:
- 将自己root加入到遍历记录表,如果有左孩子调用当前函数深度优先遍历左子树,返回后将遍历记录表中的左孩子弹出,
- 如果有右孩子调用当前函数深度优先遍历右子树,同理返回后也要将右孩子从遍历记录表中删掉。
- 返回上一层。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def __init__(self):
self.route_list = []
def front(self, root, route: str):
if root.left is None and root.right is None:
tmp_route = route + "->{}".format(root.val)
self.route_list.append(tmp_route[2:])
return
else:
if root.left:
self.front(root.left, route + "->{}".format(root.val))
if root.right:
self.front(root.right, route + "->{}".format(root.val))
return
def binaryTreePaths(self, root: Optional[TreeNode]) -> List[str]:
if root is None:
return self.route_list
else:
self.front(root, "")
return self.route_list
题中要求每个路径时带箭头的字符串。 另外不一定要每层回收,如果用我这种传参方式不需要删除左孩子和右孩子。
2.看完文档
文档链接 思路和递归+隐形回溯的python代码完全一致
3.学习时长
30分钟。
404.左叶子之和
1.第一想法
我原来想的就是要判断root.left.left和root.left.right是否都为空,如果为空那么root.left就是左叶子,确实也没有别的办法。求证了文档发现确实是要这么判断的。
2.看完文档
- 传入参数:根节点
- 返回参数:以这个节点为根节点的所有左叶子节点的和。
- 本层逻辑:判断是否有左孩子,左孩子是否还有左右孩子,如果符合左叶子标准,就获得左叶子的值。判断是否有右孩子,如果有,调用当前函数,让右孩子为root节点,获得他的左叶子的和。然后将当前左叶子的值+右孩子提供的左叶子和。
- 终止条件:如果当前节点为None或者为叶子节点则返回0,因为这两种情况都没有左叶子节点。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def sumOfLeftLeaves(self, root: Optional[TreeNode]) -> int:
if root is None:
return 0
elif (not root.left) and (not root.right):
return 0
else:
left_sum = 0
right_sum = 0
if root.left:
if (not root.left.left) and (not root.left.right):
left_sum = root.left.val
else:
left_sum = self.sumOfLeftLeaves(root.left)
if root.right:
right_sum = self.sumOfLeftLeaves(root.right)
return left_sum + right_sum
3.学习时长
50分钟。