513. 找树左下角的值
给定一个二叉树,在树的最后一行找到最左边的值。
示例 1:
示例 2:
第一种方法(递归法-只要保证优先左边搜索,无中间节点的处理逻辑):
# 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 findBottomLeftValue(self, root: Optional[TreeNode]) -> int:
maxDepth = 0
result = 0
def traversal(node, depth):
nonlocal maxDepth, result
if not node.left and not node.right:
if depth > maxDepth:
result = node.val
maxDepth = depth
if node.left:
depth += 1
traversal(node.left, depth)
depth -= 1
if node.right:
depth += 1
traversal(node.right, depth)
depth -= 1
return result
return traversal(root, 1)
第二种方法(层序遍历-借助队列):
# 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 findBottomLeftValue(self, root: Optional[TreeNode]) -> int:
que = collections.deque([root]) # 转化为数组才能传入队列
result = 0
while que:
for i in range(len(que)):
node = que.popleft()
if i == 0:
result = node.val
if node.left:
que.append(node.left)
if node.right:
que.append(node.right)
return result
112. 路径总和
给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。
说明: 叶子节点是指没有子节点的节点。
示例: 给定如下二叉树,以及目标和 sum = 22,
返回 true, 因为存在目标和为 22 的根节点到叶子节点的路径 5->4->11->2。
第一种方法(递归法):
# 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 hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:
if root:
if not root.left and not root.right and root.val == targetSum:
return True
elif not root.left and not root.right and root.val != targetSum:
return False
targetSum -= root.val
def traversal(node, count):
if node:
if not node.left and not node.right:
if count == 0:
return True
if count != 0:
return False
if node.left:
count -= node.left.val
if traversal(node.left, count):
return True
count += node.left.val
if node.right:
count -= node.right.val
if traversal(node.right, count):
return True
count += node.right.val
return False
return traversal(root, targetSum)
113. 路径总和 II
给定一个二叉树和一个目标和,找到所有从根节点到叶子节点路径总和等于给定目标和的路径。
说明: 叶子节点是指没有子节点的节点。
示例: 给定如下二叉树,以及目标和 sum = 22,
第一种方法(递归法):
# 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.result = []
self.path = []
def traversal(self, cur, count):
if not cur:
return
if not cur.left and not cur.right and count == 0: # 遇到了叶子节点且找到了和为sum的有效路径
self.result.append(self.path[:])
return
if not cur.left and not cur.right: # 遇到叶子节点而没有找到合适的边,直接返回
return
if cur.left: # 左 (空节点不遍历)
self.path.append(cur.left.val)
count -= cur.left.val
self.traversal(cur.left, count) # 递归
count += cur.left.val # 回溯
self.path.pop() # 回溯
if cur.right: # 右 (空节点不遍历)
self.path.append(cur.right.val)
count -= cur.right.val
self.traversal(cur.right, count) # 递归
count += cur.right.val # 回溯
self.path.pop() # 回溯
return
def pathSum(self, root: Optional[TreeNode], targetSum: int) -> List[List[int]]:
self.result.clear()
self.path.clear()
if not root:
return self.result
self.path.append(root.val) # 把根节点放进路径
self.traversal(root, targetSum - root.val)
return self.result
106. 从中序与后序遍历序列构造二叉树
根据一棵树的中序遍历与后序遍历构造二叉树。
注意: 你可以假设树中没有重复的元素。
例如,给出
- 中序遍历 inorder = [9,3,15,20,7]
- 后序遍历 postorder = [9,15,7,20,3] 返回如下的二叉树:
第一种方法(递归法):
# 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 buildTree(self, inorder: List[int], postorder: List[int]) -> Optional[TreeNode]:
# 后序数组为空,终止
if not postorder:
return
# 后序数组最后一个元素为当前中间节点元素
root_val = postorder[-1]
root = TreeNode(root_val)
# 如果后序数组只剩一个元素,说明是叶子节点,返回节点给上个节点左或右孩子
if len(postorder) == 1:
return root
# 找切割点
separator_idx = inorder.index(root_val)
# 切割中序数组
inorder_left = inorder[:separator_idx]
inorder_right = inorder[separator_idx + 1:]
# 切割后序数组(左中序数组和左后序数组大小相等)
postorder_left = postorder[:len(inorder_left)]
postorder_right = postorder[len(inorder_left):len(postorder) - 1]
# 递归
root.left = self.buildTree(inorder_left, postorder_left)
root.right = self.buildTree(inorder_right, postorder_right)
return root