513.找树左下角的值
本题可以利用最简单的层序遍历,进行求解,在层序遍历的过程中,取最左侧的结点即可。
本题判断最后一行最靠左侧的结点:满足最后一行的最靠左侧
- 前:中左右
- 中:左中右 √ :因为需要使用左右节点即可,不需要对中间结点进行返回
- 后:左右中
# 修改全局变量方式的递归;返回相应值的递归
maxDepth = 0
result = 0
def traversal(root,depth):
# 确定终止条件,深度最大的叶子结点中最左侧的节点
if root.left is null and root.right is null:
if depth > maxdepth:
maxdepth = depth
result = root.val # 不断更新即可,
if root.left:
depth ++
traversal(node.left,depth)
depth-- # 回溯的过程
if root.right:
depth ++
traversal(node.right,depth)
depth-- # 回溯的过程
# 没有中的处理逻辑,因为本题没有中结点的处理逻辑
反思:
- 注意遍历时候终止条件的确定,本题中在碰到叶子结点时触发相应的终止条件。
- 设置全局变量,递归改变的是全局变量的值。
# 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.maxDepth = -1
self.result = -1
def getLeft(self, node, depth):
if not node:
return
if not node.left and not node.right:
if self.maxDepth < depth:
self.maxDepth = depth
self.result = node.val
self.getLeft(node.left, depth+1)
self.getLeft(node.right, depth+1)
def findBottomLeftValue(self, root: Optional[TreeNode]) -> int:
self.getLeft(root,0)
return self.result
112. 路径总和 &113.路径总和ii
B站讲解:
递归+回退: 每一步递归返回的都是布尔类型的值,当前路径中是否可能存在满足targetNum的值。回溯的过程存在于,当计算得到的值,不满足当前的条件时,返回该值即可。
思考: 不需要将每一个叶子结点都进行遍历,只需要找到一个叶子结点,然后找到该叶子结点是否符合要求即可。
class Solution:
def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:
def isornot(root, targetsum) -> bool:
if (not root.left) and (not root.right) and targetsum == 0:
return True # 遇到叶子节点,并且计数为0
if (not root.left) and (not root.right):
return False # 遇到叶子节点,计数不为0
if root.left:
targetsum -= root.left.val # 左节点
if isornot(root.left, targetsum): return True # 递归,处理左节点
targetsum += root.left.val # 回溯
if root.right:
targetsum -= root.right.val # 右节点
if isornot(root.right, targetsum): return True # 递归,处理右节点
targetsum += root.right.val # 回溯
return False
if not root:
return False # 别忘记处理空treenode
else:
return isornot(root, targetSum - root.val)
# 路径总和II
# 注意本题中
class Solution:
def pathSum(self, root: Optional[TreeNode], targetSum: int) -> List[List[int]]:
# 修正全局变量的值,因而不需要进行返回值的求解
# 在处理result的过程中需要注意
result = []
tmp = []
def dfs(root, tmp, targetsum):
# 当前节点,当前结点对应的targetSum
if not root:
return
tmp.append(root.val) # 子节点
targetsum -= root.val
if (not root.left) and (not root.right) and targetsum == 0:
result.append(tmp.copy())
else:
if root.left:
dfs(root.left, tmp, targetsum) # 递归,处理左节点
tmp.pop() # 运行完之后pop当前的值找到上一层结点
if root.right:
dfs(root.right, tmp, targetsum) # 递归,处理右节点
tmp.pop()
# 进行深度优先搜索
dfs(root,tmp,targetSum)
if not root:
return [] # 别忘记处理空treenode
else:
return result
自己探索:
class Solution:
''' # 本人代码
def __init__(self):
self.flag = -1
def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:
# 递归法,后续遍历中左右
# 利用result记录
def traversal(node,value):
if not node.left and not node.right and value == targetSum:
# 如果找到一个路径之和等于目标值的,中左右的顺序
self.flag = 1
if node.left:
traversal(node.left,value + node.left.val)
if node.right:
traversal(node.right,value + node.right.val)
if not root:
return False
traversal(root, root.val)
if self.flag == 1: return True
else: return False
106.从中序与后序遍历序列构造二叉树 &105.从前序与中序遍历序列构造二叉树
基础知识:
中序:左中右
后序:左右中
tips: 后序和前序不能唯一确定的二叉树,因为只能确定中,不能确定左右区间的分割点。而中序+后序&中序+前序都可以唯一确定一个二叉树
基本步骤:
利用递归的方法对该问题进行求解,每一层涉及到了相同的结构。
- 后序数组为0,空结点
- 后序书序的最后一个元素为结点元素
- 寻找中序数组的位置作为切割点
- 切割中序数组(注意统一区间的规则)
- 切割后序数组(注意统一区间的规则)
- 递归处理相应的左区间和右区间
# 后序+中序
class Solution:
def buildTree(self, inorder: List[int], postorder: List[int]) -> Optional[TreeNode]:
if not postorder:
return
val = postorder[-1]
index_val = inorder.index(val)
# 对前序和中序数组进行切割
root = TreeNode(val)
leftInorder,rightInorder = inorder[0:index_val] , inorder[index_val+1:]
leftPostorder,rightPostorder = postorder[0:len(leftInorder)], postorder[len(leftInorder):len(postorder)-1]
root.left = self.buildTree(leftInorder,leftPostorder)
root.right = self.buildTree(rightInorder,rightPostorder)
return root
# 前序+中序
class Solution:
def buildTree(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]:
if not preorder:
return
val = preorder[0]
index_val = inorder.index(val)
# 对前序和中序数组进行切割
root = TreeNode(val)
leftInorder,rightInorder = inorder[0:index_val] , inorder[index_val+1:]
leftpreorder,rightpreorder = preorder[1:len(leftInorder)+1], preorder[len(leftInorder)+1:len(preorder)]
root.left = self.buildTree(leftpreorder,leftInorder)
root.right = self.buildTree(rightpreorder,rightInorder)
return root