这篇可以主要关注一下如何确定递归时是否需要返回值。

LC513. 找树左下角的值

给定一个二叉树的根节点,请找出该二叉树的 最底层最左边 节点的值。

思路1 层序遍历

class Solution:def findBottomLeftValue(self, root: Optional[TreeNode]) -> int:if not root: return -1# leverOrderfrom collections import dequeque = deque()que.append(root)while que:size = len(que)for i in range(size):node = que.popleft()if i == 0:ans = node.valif node.left: que.append(node.left)if node.right: que.append(node.right)return ans

思路2 深度优先方法要困难一些,递归判断结点是否是深度最大的叶子结点,只遍历,没有进行什么操作,所以不需要有返回值。这种写法是隐含了回溯的,不需要自己写,因为函数调用完形参就释放了。

class Solution:def findBottomLeftValue(self, root: Optional[TreeNode]) -> int:def isleaf(root):return root and not root.left and not root.right# 深度优先 max_depth = 0target = root.valdef dfs(root, depth):nonlocal max_depth, targetif not root: return depth += 1if isleaf(root):if depth > max_depth:max_depth = depthtarget = root.valdfs(root.left, depth)dfs(root.right, depth)dfs(root, 0)return target

下面这种写法是把回溯写出来了,因为depth一直在变的。

class Solution:def findBottomLeftValue(self, root: Optional[TreeNode]) -> int:def isleaf(root):return root and not root.left and not root.rightleftval = root.valmax_d = 0depth = 0def dfs(root):nonlocal leftval, max_d, depthif not root: returndepth += 1if isleaf(root):if depth > max_d:max_d = depthleftval = root.valif root.left:dfs(root.left)depth -= 1if root.right:dfs(root.right)depth -= 1dfs(root)return leftval

LC112. 路径总和​​​​​​

给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false。

下面是我自己的写法,虽然AC了(其中要注意ans写成nonlocal),但是问题是找到了目标路径和之后还是会进行一整个树的遍历。

class Solution:def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:def isleaf(root):return root and not root.left and not root.right# 先序遍历ans = Falsepathsum = 0def dfs(root, pathsum):nonlocal ansif not root: return pathsum += root.valif isleaf(root):if pathsum == targetSum:ans = Trueif root.left: dfs(root.left, pathsum)if root.right: dfs(root.right, pathsum)dfs(root,pathsum)return ans

本题搜索出一条符合条件的路径即可,所以递归一定要有返回值,遇到符合的路径要及时返回。下面的写法好多了。

class Solution:def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:def isleaf(root):return root and not root.left and not root.right# 先序遍历def dfs(root, pathsum) -> bool:pathsum += root.val# 叶子结点如果找到了路径和,True;否则Falseif isleaf(root):if pathsum == targetSum:return Trueelse:return False# 如果左孩子里面找到了路径和,返回Trueif root.left: if dfs(root.left, pathsum):return True# 如果右孩子里面找到了路径和,返回Trueif root.right: if dfs(root.right, pathsum):return True# 都没有找到,返回Falsereturn Falseif not root: return False #这一行也重要return dfs(root,0)

LC113. 路径总和 II

给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有从根节点到叶子节点路径总和等于给定目标和的路径。

本题是需要遍历完整棵树,且不用处理递归返回值,就不需要返回值。

class Solution:def pathSum(self, root: Optional[TreeNode], targetSum: int) -> List[List[int]]:def isleaf(root):return root and not root.left and not root.rightpaths = []path = []def dfs(root, sum_pre):if not root: returnpath.append(root.val)sum_pre += root.val# print(sum_pre, path)if isleaf(root) and sum_pre == targetSum: #写的时候isleaf后面的(root)也忘了写,就变成了是否存在isleaf函数,就一直都是True。多花了时间调试,写的时候就要慢慢细致地写。paths.append(path[:]) #[:]不要忘了加if root.left:dfs(root.left, sum_pre)path.pop()if root.right:dfs(root.right, sum_pre)path.pop()dfs(root, 0)return paths

LC106. 从中序与后序遍历序列构造二叉树​​​​​​​

这题没有看答案一次AC了,大晚上的开心了好一会儿~这草稿也是只有自己能看懂了LOL。

本题需要遍历完整棵树,但需要对递归返回值(结点)进行处理(链接),所以需要有返回值。

# 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 find(self, nums, val):for i, num in enumerate(nums):if num == val:return ireturn -1def buildTree(self, inorder: List[int], postorder: List[int]) -> Optional[TreeNode]:# def constructTree(inorder, postorder: List[int]) -> Optional[TreeNode]:if not inorder: return Noneif len(inorder) == 1: return TreeNode(inorder[0])m = postorder[-1]node = TreeNode(m)i = self.find(inorder, m)print(m,i)l_inorder = inorder[0:i]r_inorder = inorder[i+1:]l_postorder = postorder[0:i]r_postorder = postorder[i:-1]node.left = self.buildTree(l_inorder,l_postorder)node.right = self.buildTree(r_inorder,r_postorder)return node

LC105. 从前序与中序遍历序列构造二叉树

给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。

和上题一样的写法,但写find函数时出现了小问题,要在循环结束时还没return才返回-1。

class Solution:def find(self, nums, val):for i, num in enumerate(nums):if num == val:return ireturn -1def buildTree(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]:if not preorder: return NoneNode = TreeNode(preorder[0])mid = preorder[0]i = self.find(inorder, mid)l_inorder, r_inorder = inorder[0:i], inorder[i+1:]l_preorder, r_preorder = preorder[1:i+1], preorder[i+1:]Node.left = self.buildTree(l_preorder, l_inorder)Node.right = self.buildTree(r_preorder, r_inorder)return Node

看了答案之后发现在list中查找元素的时候,不需要自己写函数,用自身的index方法,直接i = inorder.index(mid)即可。

明天加油~

参考资料:​​​​​​​路径总和-代码随想录

找树左下角的值+路径总和+从前序和中序遍历序列构造二叉树(day18*)相关推荐

  1. 二叉树 中序遍历 python_LeetCode 105 树 从前序与中序遍历序列构造二叉树(Medium)

    17(105) 从前序与中序遍历序列构造二叉树(Medium) 描述 根据一棵树的前序遍历与中序遍历构造二叉树. 注意: 你可以假设树中没有重复的元素. 示例 例如,给出前序遍历 preorder = ...

  2. java二叉树合并_Java(树的前中后序遍历构造二叉树题型整合)前序和中序、中序和后序、前序和后序遍历序列构造二叉树算法整合归纳...

    前言 二叉树各种花里胡哨的算法题真的把我搞晕了,今天特地整理出一类有关二叉树的算法题,希望能帮助阅读到此文章的人,今后不再受此类题型的困扰. 一.题目类型 已知二叉树的两种遍历序列,请根据该序列构建二 ...

  3. Suzy找到实习了吗Day 18 | 二叉树进行中:513 找树左下角的值,112 路径总和 ,106.从中序与后序遍历序列构造二叉树

    513 找树左下角的值 solution # Definition for a binary tree node. # class TreeNode: # def __init__(self, val ...

  4. 代码随想录第18天|找树左下角的值,路径总和,从中序和后序遍历序列构造二叉树

    LeetCode513.找树左下角的值 题目链接:513. 找树左下角的值 - 力扣(LeetCode) 思路: 迭代法(只需要记录最后一行第一个节点的数值就可以了.): /*** Definitio ...

  5. educoder数据结构 树 第1关:由双遍历序列构造二叉树

    目录 任务描述 编程要求 代码实现 任务描述 本关任务:实现 ConstructTree.cpp 里的TNode* InPreToTree(char *pa, char *ia, int p1, in ...

  6. Java实现 LeetCode 513 找树左下角的值

    513. 找树左下角的值 给定一个二叉树,在树的最后一行找到最左边的值. 示例 1: 输入: 2/ \1 3 输出: 1 示例 2: 输入: 1/ \2 3/ / \ 4 5 6/7 输出: 7 注意 ...

  7. 树与二叉树 | 实验3:由遍历序列构造二叉树

    实验3:由遍历序列构造二叉树 二叉树构造定理: 定理7.1:任何n(n>0)个不同结点的二又树,都可由它的中序序列和先序序列唯一地确定. 定理7.2:任何n(n>0)个不同结点的二又树,都 ...

  8. 由标明空子树的先序遍历序列创建二叉树

    由标明空子树的先序遍历序列创建二叉树 i=0 def createBiTree2(preOrder): # i为常数0 global i c = preOrder[i] # 取字符 if c != ' ...

  9. C语言学习笔记——根据二叉树的后序和中序遍历序列,求这棵树的先序和层次遍历序列

    先根据二叉树的后序和中序遍历序列,用递归的方法创建出这棵树,然后用的自定义栈的先序和层次方法遍历. 输入:  7 2 3 1 5 7 6 4                      1 2 3 4 ...

最新文章

  1. 书写是为了更好的思考
  2. [Android]用架构师角度看插件化(2)-Replugin 唯一hook点
  3. 实验三 静态路由、默认路由配置
  4. 你未必知道的49个CSS知识点
  5. SAP Spartacus 中的依赖注入 Dependency Injection 介绍
  6. 小型金融知识图谱构流程示范
  7. c语言编译asn1文件,使用 asn1.c 开源编译工具生成 S1AP R15消息编解码C文件
  8. xshell停止运行脚本_Xshell无法启动:要继续使用此程序,您必须应用最新的更新或使用新版本...
  9. linux 程序收到sigsegv信号_Linux基础知识(五)
  10. 在linux系统下安装oracle前的准备工作(配置oracle环境变量)
  11. 南京申瓯SOC1000-UC IPPBX为中小企业提供电话系统解决方案
  12. 为什么更多APP开发者选择穿山甲作为游戏变现平台?
  13. vue手机端回退_从外链回退到vue应用不触发生命周期、beforeRouterEnter等钩子函数的问题...
  14. thinkpad T480 ubuntu 16.04安装无线网卡rtl8821ce驱动
  15. 惊呆了!692分的学霸都想当程序员,理由居然是
  16. 支持HEVC/H265 RTMP接收的FFMPEG/FFPLAY WINDOWS版本
  17. 【强化学习】Actor-Critic(演员-评论家)算法详解
  18. Prometheus 监控基础
  19. YOLOV3在windwos下的配置和训练过程简述
  20. 不想进大厂的程序员是没有梦想的,2021年阿里、腾讯,java架构师指南百度云

热门文章

  1. 网络互联及Internet
  2. Windows11便签工具在哪 win11的便签在哪里打开
  3. html5 倒计时跳转动画,HTML5弹性摇摆旋转的倒计时动画
  4. 怎么保存python文件_pycharm怎么保存py文件
  5. Android下的弹幕的简单实现
  6. androi的AT指令
  7. verilog语言实现全加器
  8. 使用 TCP / IP 套接字(Sockets)
  9. ImageIO类的使用
  10. tomcat启动后无法访问到8080页面的原因