513. 找树左下角的值
迭代法层次遍历
- return最后访问的值即可
- 从右往左进队列
class Solution:
def findBottomLeftValue(self, root: Optional[TreeNode]) -> int:
q = deque([root])
res = None
while q:
l = len(q)
for _ in range(l):
cur = q.popleft()
res = cur.val
if cur.right:
q.append(cur.right)
if cur.left:
q.append(cur.left)
return res
递归法(使用dict存放层最左边的节点)
class Solution:
def findBottomLeftValue(self, root: Optional[TreeNode]) -> int:
depth_map = {}
depth = 0
self.map_depth_to_value(root, depth, depth_map)
return list(depth_map.items())[-1][1]
def map_depth_to_value(self, root, depth, depth_map):
# only record the left most node in each depth
# root
if depth not in depth_map:
depth_map[depth] = root.val
depth += 1
# left
if root.left:
self.map_depth_to_value(root.left, depth, depth_map)
# right
if root.right:
self.map_depth_to_value(root.right, depth, depth_map)
递归法(一直记录遍历到当前节点为止的最大深度和对应的最左边的节点)
class Solution:
def findBottomLeftValue(self, root: Optional[TreeNode]) -> int:
left_node_val = None
max_depth = -1
def helper(cur, cur_depth):
nonlocal max_depth, left_node_val
# leaf node
if not cur.left and not cur.right:
if cur_depth > max_depth:
left_node_val = cur.val
max_depth = cur_depth
if cur.left:
helper(cur.left, cur_depth+1)
if cur.right:
helper(cur.right, cur_depth+1)
helper(root, 0)
return left_node_val
112. 路径总和
递归法(计算所有path的和)
- 前序遍历
class Solution:
def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:
if not root:
return False
res = []
path_sum = 0
self.get_path_sum(root, path_sum, res)
return targetSum in res
def get_path_sum(self, root, path_sum, res):
# root
path_sum += root.val
if not root.left and not root.right:
res.append(path_sum)
# left
if root.left:
self.get_path_sum(root.left, path_sum, res)
# right
if root.right:
self.get_path_sum(root.right, path_sum, res)
递归法(更新target值)
class Solution:
def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:
if not root:
return False
# leaf node
if not root.left and not root.right:
return root.val == targetSum
targetSum -= root.val
# left or right
return self.hasPathSum(root.left, targetSum) or self.hasPathSum(root.right, targetSum)
迭代法(栈模拟前序遍历)
class Solution:
def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:
if not root:
return False
stack = deque([(root, 0)])
while stack:
cur, path_sum = stack.pop()
path_sum += cur.val
# leaf node
if not cur.left and not cur.right and path_sum == targetSum:
return True
if cur.left:
stack.append((cur.left, path_sum))
if cur.right:
stack.append((cur.right, path_sum))
return False
113. 路径总和 II
递归法
- 使用
path[:]保留当时的path的值
class Solution:
def pathSum(self, root: Optional[TreeNode], targetSum: int) -> List[List[int]]:
if not root:
return []
def helper(root, remain):
if not root.left and not root.right and remain == 0:
res.append(path[:])
return
if root.left:
path.append(root.left.val)
helper(root.left, remain - root.left.val)
path.pop()
if root.right:
path.append(root.right.val)
helper(root.right, remain - root.right.val)
path.pop()
res, path = [], [root.val]
helper(root, targetSum - root.val)
return res
106. 从中序与后序遍历序列构造二叉树
递归法
-
利用postorder和inorder的遍历顺序,不断找到子树的根节点并进行连接
- 根节点为postorder的最后一个元素,利用这个元素去分割inorder(根节点元素在list中间,左右子树在两边)
- 利用左右子树所包含的节点数是一样的特性,把在inorder中找到的左右子树的大小用来分割postorder(左子树在前,右子树在后)
class Solution:
def buildTree(self, inorder: List[int], postorder: List[int]) -> TreeNode:
if not inorder and not postorder:
return None
# root is the last value in postorder
root_val = postorder[-1]
# use root to partition inorder list
index = inorder.index(root_val)
left_in_part = inorder[:index]
right_in_part = inorder[index+1:]
# use left and right part to partition postorder list
left_post_part = postorder[:len(left_in_part)]
right_post_part = postorder[len(left_in_part):len(left_in_part)+len(right_in_part)]
root = TreeNode(root_val)
root.left = self.buildTree(left_in_part, left_post_part)
root.right = self.buildTree(right_in_part, right_post_part)
return root
105. 从前序与中序遍历序列构造二叉树
- 一样的思路
class Solution:
def buildTree(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]:
if not preorder and not inorder:
return None
# root is the first value in preorder
root_val = preorder[0]
# use root to partition inorder list
index = inorder.index(root_val)
left_in_part = inorder[:index]
right_in_part = inorder[index+1:]
# use left and right part to partition preorder list
left_pre_part = preorder[1 : 1+len(left_in_part)]
right_pre_part = preorder[1+len(left_in_part) : ]
root = TreeNode(root_val)
root.left = self.buildTree(left_pre_part, left_in_part)
root.right = self.buildTree(right_pre_part, right_in_part)
return root