513.找树左下角的值
题目链接/文章讲解/视频讲解:代码随想录
思路:首先要是最后一行,然后是最左边的值。
如果使用递归法,如何判断是最后一行呢,其实就是深度最大的叶子节点一定是最后一行。
如果对二叉树深度和高度还有点疑惑的话,请看:110.平衡二叉树 (opens new window)。
所以要找深度最大的叶子节点。
那么如何找最左边的呢?可以使用前序遍历(当然中序,后序都可以,因为本题没有 中间节点的处理逻辑,只要左优先就行),保证优先左边搜索,然后记录深度最大的叶子节点,此时就是树的最后一行最左边的值。
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:
if not root:
return None
que = deque()
que.append(root)
result = 0
while que:
size = len(que)
for i in range(size):
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
2.递归法
递归三部曲:
1.确定递归函数的参数和返回值
本题还需要类里的两个全局变量,maxLen用来记录最大深度,result记录最大深度最左节点的数值。
def traversal(self,node,depth)
2.确定终止条件
当遇到叶子节点的时候,就需要统计一下最大的深度了,所以需要遇到叶子节点来更新最大深度。
if not node.left and not node.right:
if depth>self.maxDepth:
self.maxDepth = depth
self.result = node.val
3.确定单层递归的逻辑
在找最大深度的时候,递归的过程中依然要使用回溯
#左
if node.left:
depth += 1
self.traversal(node.left,depth)
depth -= 1
#右
if node.right:
depth += 1
self.traversal(node.right,depth)
depth -= 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:
self.maxDepth = float('-inf')
self.result = None
self.traversal(root,0)
return self.result
def traversal(self,node,depth):
if not node.left and not node.right:
if depth>self.maxDepth:
self.maxDepth = depth
self.result = node.val
#左
if node.left:
depth += 1
self.traversal(node.left,depth)
depth -= 1
#右
if node.right:
depth += 1
self.traversal(node.right,depth)
depth -= 1
112. 路径总和 113.路径总和ii
题目链接/文章讲解/视频讲解:代码随想录
112.路径总和
自己是效仿257. 二叉树的所有路径写的
# 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):
path = []
result = []
if not root:
return False
self.pathSum(root,path,result)
if targetSum in result:
return True
else:
return False
def pathSum(self,node,path,result):
#中
path.append(node.val)
if not node.left and not node.right:
result.append(sum(path))
#左
if node.left:
self.pathSum(node.left,path,result)
path.pop()
#右
if node.right:
self.pathSum(node.right,path,result)
path.pop()
本题我们要找一条符合条件的路径,所以递归函数需要返回值,及时返回,

图中可以看出,遍历的路线,并不要遍历整棵树,所以递归函数需要返回值,可以用bool类型表示。
# 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):
if not root:
return False
return self.traversal(root,targetSum-root.val)
def traversal(self,cur,count):
if not cur.left and not cur.right and count == 0:
return True
if not cur.left and not cur.right and count != 0:
return False
if cur.left:
count -= cur.left.val
if self.traversal(cur.left,count):
return True
count += cur.left.val
if cur.right:
count -= cur.right.val
if self.traversal(cur.right,count):
return True
count += cur.right.val
return False
113.路径总和-ii(这道题要再复习)
# 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.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: TreeNode, sum: int) -> List[List[int]]:
self.result.clear()
self.path.clear()
if not root:
return self.result
self.path.append(root.val) # 把根节点放进路径
self.traversal(root, sum - root.val)
return self.result
106.从中序与后序遍历序列构造二叉树 105.从前序与中序遍历序列构造二叉树
题目链接/文章讲解/视频讲解:代码随想录
106.从中序与后序遍历序列构造二叉树
-
第一步:如果数组大小为零的话,说明是空节点了。
-
第二步:如果不为空,那么取后序数组最后一个元素作为节点元素。
-
第三步:找到后序数组最后一个元素在中序数组的位置,作为切割点
-
第四步:切割中序数组,切成中序左数组和中序右数组 (顺序别搞反了,一定是先切中序数组)
-
第五步:切割后序数组,切成后序左数组和后序右数组
-
第六步:递归处理左区间和右区间
# 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 None
#找到根节点
root_val = postorder[-1]
root = TreeNode(root_val)
#找切割点
sep_id = inorder.index(root_val)
#中序切割
in_left = inorder[:sep_id]
in_right = inorder[sep_id+1:]
#后序切割
pos_left = postorder[:len(in_left)]
pos_right = postorder[len(in_left):len(postorder)-1]
#递归
root.left = self.buildTree(in_left,pos_left)
root.right = self.buildTree(in_right,pos_right)
return root
105.从前序与中序遍历序列构造二叉树
思路跟106一样
# 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 not preorder:
return None
#找根节点
root_val = preorder[0]
root = TreeNode(root_val)
#找分割值
sep_id = inorder.index(root_val)
#分割中序数组
in_left = inorder[:sep_id]
in_right = inorder[sep_id+1:]
#分割前序数组
pre_left = preorder[1:len(in_left)+1]
pre_right = preorder[len(in_left)+1:]
#递归
root.left = self.buildTree(pre_left,in_left)
root.right = self.buildTree(pre_right,in_right)
return root
1491

被折叠的 条评论
为什么被折叠?



