第六章 二叉树(五)
主要内容
- 二叉树递归迭代
- 二叉树构造
题目
513.找树左下角的值
题目描述
思路分析
- 可以迭代层次遍历
- 思考递归,回溯
代码
迭代层次遍历
# 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:
if not root:
return None
from collections import deque
que = deque([root])
results = []
while que:
l = len(que)
res = []
for _ in range(l):
cur = que.popleft()
res.append(cur.val)
if cur.left:
que.append(cur.left)
if cur.right:
que.append(cur.right)
results.append(res)
return results[-1][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 findBottomLeftValue(self, root: Optional[TreeNode]) -> int:
result = 0
maxdepth = -float("inf")
def _traverse(root, cur_depth):
# nonlocal用于嵌套函数中,标识该变量是上一层函数的局部变量
nonlocal result, maxdepth
# 终止条件,遇到叶子节点
if not root.left and not root.right:
if cur_depth > maxdepth:
maxdepth = cur_depth
result = root.val
if root.left:
# 回溯
cur_depth += 1
_traverse(root.left, cur_depth)
cur_depth -= 1
if root.right:
# 回溯
cur_depth += 1
_traverse(root.right, cur_depth)
cur_depth -= 1
_traverse(root, 0)
return result
112. 路径总和
题目描述
思路分析
带有回溯的递归
代码
# 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:
result = False
if not root:
return result
def _traverse(root, sumtemp):
nonlocal result
# 终止条件,遇到叶子节点
if not root.left and not root.right:
if sumtemp == targetSum:
result = True
if root.left:
# 回溯
sumtemp += root.left.val
_traverse(root.left, sumtemp)
sumtemp -= root.left.val
if root.right:
# 回溯
sumtemp += root.right.val
_traverse(root.right, sumtemp)
sumtemp -= root.right.val
_traverse(root, root.val)
return result
113.路径总和ii
题目描述
思路分析
# 疑问,为什么要用[:]
results.append(path[:])
# 为什么不能直接append(path)
#results.append(path)
用path[:] 相当于是把内容copy出来,直接append是传的对象,会随着path变化,results也变化
代码
# 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 pathSum(self, root: Optional[TreeNode], targetSum: int) -> List[List[int]]:
results = []
if not root:
return results
def _traverse(root, path, tempsum):
nonlocal results
if not root.left and not root.right:
if tempsum == targetSum:
# 疑问,为什么要用[:]
results.append(path[:])
# 为什么不能直接append(path)
#results.append(path)
if root.left:
tempsum += root.left.val
path.append(root.left.val)
_traverse(root.left, path, tempsum)
tempsum -= root.left.val
path.pop()
if root.right:
tempsum += root.right.val
path.append(root.right.val)
_traverse(root.right, path, tempsum)
tempsum -= root.right.val
path.pop()
_traverse(root, [root.val], root.val)
return results
106.从中序与后序遍历序列构造二叉树
题目描述
思路分析
从后序最后一位找到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 buildTree(self, inorder: List[int], postorder: List[int]) -> Optional[TreeNode]:
if len(postorder) == 0:
return None
# 从后序最后一位找到root
rootval = postorder[-1]
root = TreeNode(rootval)
# 切割中序数组
rootindex = inorder.index(rootval)
leftinorder = inorder[:rootindex]
rightinorder = inorder[rootindex+1:]
# 切割后序数组
postorder.pop() # 弹出root
leftpostorder = postorder[:rootindex]
rightpostorder = postorder[rootindex:]
root.left = self.buildTree(leftinorder, leftpostorder)
root.right = self.buildTree(rightinorder, rightpostorder)
return root
105.从前序与中序遍历序列构造二叉树
题目描述
思路分析
从前序中第一位找到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 buildTree(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]:
if len(preorder) == 0:
return None
# 从前序中第一位找到root
rootval = preorder[0]
root = TreeNode(rootval)
preorder.pop(0)
# 切割中序数组
rootindex = inorder.index(rootval)
leftinorder = inorder[:rootindex]
rightinorder = inorder[rootindex+1:]
# 切割前序数组
leftpreorder = preorder[:rootindex]
rightpreorder = preorder[rootindex:]
# 递归左右子树
root.left = self.buildTree(leftpreorder, leftinorder)
root.right = self.buildTree(rightpreorder, rightinorder)
return root