- √ 513 找树左下角的值
- √ 112 路径总和
- √ 113 路径总和
106 从中序与后序遍历序列构造二叉树(掌握算法)
小点总结:
- 路径的回溯:在递归返回时,需要将当前节点的值从 temp_list 中移除(pop),以确保下一次递归调用时路径是正确的。
- 养成习惯:函数体中所有情况均有return,不遗漏
- 全局变量与传参
513 找树左下角的值
- 也就是 深度优先搜索
- 使用height记录深度
- 在内部函数中,XXX使用前标记他们( curlevel 和 curval)
为全局变量
class Solution:
def findBottomLeftValue(self, root: Optional[TreeNode]) -> int:
curval = root.val
curlevel = 0
def bianli(node, height):
if node is None:
return
height +=1
bianli(node.left,height)
bianli(node.right,height)
nonlocal curval,curlevel
if height> curlevel:
curlevel = height
curval = node.val
bianli(root,0)
return curval
112 路径总和
- 递归再增知识点:self.function
- 这阵子写习惯了 多写一个 function作为迭代子函数,忘了本身就可以 作为迭代函数了,下面就是 self的示范
- 同时注意传参的讲究,要求 节点val的sum == targetSum,不见sum只看targetSum,一路 targetSum - node.val,棒。
def hasPathSum(self, node: Optional[TreeNode], targetSum: int) -> bool:
if not node:
return False
if not node.left and not node.right:
if node.val == targetSum:
return True
else:
return False
return self.hasPathSum(node.left, targetSum - node.val) or self.hasPathSum(node.right, targetSum - node.val)
稍逊版本:
function diedai() 现在来看有点多余了
注意一个点: 后面的 return 传参传的是 + node.val ,并不包括 node.left.val / node.right.val,那么在 if == 处的时候需要 再+ node.val。
因此,还可以提升,仅在 if not node判断完后,cursum += node.val,其余地方不该改变cursum的值。
def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:
def diedai(node,cursum):
if not node:
return False
if not node.left and not node.right:
nonlocal targetSum
if cursum + node.val == targetSum:
return True
else:
return False
return diedai(node.left,cursum+node.val) or diedai(node.right,cursum+node.val)
return diedai(root,0)
113 路径总和
果然,中等难度比112小朋友高一点,思路上就存在些许漏洞,先说一个基本的
在使用list1进行赋值给list2,注意给的是地址,那么若赋值后,若list1改变,list2也将改变
该题注意点:
注意,记录路径的时候要注意pop, pop现在这个节点,有点回溯到上个节点的意思
class Solution:
def pathSum(self, root: Optional[TreeNode], targetSum: int) -> List[List[int]]:
ans_list = []
def hasPathSum(node: Optional[TreeNode], targetSum: int,temp_list:List[int]):
if not node:
return
temp_list.append(node.val)
if not node.left and not node.right:
nonlocal ans_list
if node.val == targetSum:
ans_list.append(temp_list.copy())
temp_list.pop()
return
hasPathSum(node.left, targetSum - node.val,temp_list)
hasPathSum(node.right, targetSum - node.val,temp_list)
temp_list.pop()
return
hasPathSum(root, targetSum,[])
return ans_list
106 从中序与后序遍历序列构造二叉树(掌握算法)
算法:
1、通过获取后序遍历的最后一个元素获取树的根节点:
理解中序遍历和后序遍历:
- 中序遍历:左根右
- 后序遍历:左右根
故:突破在 后序遍历的最后一个元素(根)
2、确定中序遍历中根节点的位置:
根节点在中序遍历中将树分为左子树和右子树。
3、递归处理左右子树:
对左子树和右子树重复上述步骤,直到所有节点都被处理
先把kimi的答案放这吧,leetcode明天刷,然后再补结果在评论区。
def buildTree(inorder, postorder):
if not inorder or not postorder:
return None
root_val = postorder[-1]
root = TreeNode(root_val)
# 找到根节点在中序遍历中的位置
inorder_index = inorder.index(root_val)
# 递归构建左右子树
root.left = buildTree(inorder[:inorder_index], postorder[:inorder_index])
root.right = buildTree(inorder[inorder_index + 1:], postorder[inorder_index:-1])
return root
def levelOrder(root):
if not root:
return []
queue = [root]
result = []
while queue:
level_size = len(queue)
current_level = []
for _ in range(level_size):
node = queue.pop(0)
current_level.append(node.val)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
result.append(current_level)
return result