代码随想录27期|Python|Day18|二叉树|路径总和iii|找树左下角的值|从中序与后序遍历序列构造二叉树

 第一次刷的时候题解都不是精简版

 513. 找树左下角的值 - 力扣(LeetCode)

注意这道题不是寻找最左侧的左节点,而是寻找最底层位于左端的节点(可能是左节点,有可能是右节点)。

层序遍历

 层序遍历比较简单,只需要查找到每一层新加入的首位元素即可。在模板基础上加上判断即可。

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):def findBottomLeftValue(self, root):""":type root: TreeNode:rtype: int"""res = 0queue = collections.deque()queue.append(root)while queue:size = len(queue)for i in range(size):cur = queue.popleft()# 当索引是队列的第一个值(也就是下一层最先被加入的节点)if i == 0:res = cur.valif cur.left:queue.append(cur.left)if cur.right:queue.append(cur.right)return res

深度递归 + 回溯

 递归(左中右)也是最先寻找到左节点,所以只需要在求解最大深度的基础上,把遍历到最大深度的第一个值取出即可。

本题回溯思路可以参考之前的求解最大深度的方法。

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):def findBottomLeftValue(self, root):""":type root: TreeNode:rtype: int"""# 深度递归 + 回溯# 用self.定义全局变量self.max_depth = float('-inf')self.res = 0self.traversal(root, 0)return self.resdef traversal(self, node, depth):  # depth 接受的是当前层的深度# 如果当前节点是叶子节点,判断当前深度是否是最大if not node.left and not node.right:# 更新最大深度if depth > self.max_depth:self.max_depth = depthself.res = node.valif node.left:depth += 1  # 深度 + 1self.traversal(node.left, depth)  # 此处传入的深度是子节点的深度depth -= 1  # 深度回溯 - 1if node.right:depth += 1self.traversal(node.right, depth)depth -= 1

 112. 路径总和 - 力扣(LeetCode)

重点是递归的返回值,传入参数,以及回溯部分的修改。

首先确定返回值,由于这一题不是遍历整个二叉树,而是找到满足条件的值就直接返回,所以返回值是bool。传入参数是需要一直更新和回溯的,这里是目标值和节点

在递归中,我们自顶向下用目标值分别减去路径上的节点值,所以在递归结束之后,需要把这个值加回来。

还需要注意:在回溯到子节点返回True的时候,意味着这条路径是可行的,但是这个True只能返回到上一级的递归函数体里面。要返回到根节点的话需要一直向上返回到root,所以在左右子节点处理的时候我们在接受到底层传进来的True的时候需要再往上返回True

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):def hasPathSum(self, root, targetSum):""":type root: TreeNode:type targetSum: int:rtype: bool"""if not root:return Falsereturn self.traversal(root, targetSum - root.val)# Step 1:传入参数(当前节点,目标值扣除当前节点值的结果)def traversal(self, node, count):# Step 2:终止条件# 1、count减到0,这条路径可行,返回给上一级if not node.left and not node.right and count == 0:return True # 2、count没减到0,这条路径标记为false,返回给上一级if not node.left and not node.right:return False# Step 3:中间处理# 左节点 if node.left:count -= node.left.val  # 先扣除左子节点的值# 如果子节点遍历结果是True,那么这条路径有效,继续返回给上一级if self.traversal(node.left, count): return Truecount += node.left.val  # 回溯返还扣除的值# 右节点if node.right:count -= node.right.valif self.traversal(node.right, count): return Truecount += node.right.valreturn False

 113. 路径总和 II - 力扣(LeetCode)

本题在上一题的基础上要求返回全部满足条件的路径。

递归法

需要注意返回值:在本题中,由于设置的是全局变量,所以在递归函数中只需要对于变量进行更新,不需要有返回值,所以是return 即可。

另外本题可以学习如何使用Python类中的全局变量。

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):def __init__(self):# 自定义全局变量保存结果和当前遍历的路径点self.res = []self.path = []# Step 1:确定返回值和参数# 由于是对于全局变量进行修改所以不需要返回值def traversal(self, node, count):# Step 2:确定终止条件# 当前节点是叶子节点,且count被减到0if not node.left and not node.right and count == 0:self.res.append(self.path[:])  # 满足条件的path全部保存return # 当前节点是叶子节点,但是不满足条件,不修改全局变量直接返回if not node.left and not node.right:return # Step 3:每次递归处理# 左节点if node.left:# 先加入路径点self.path.append(node.left.val)# count值减去左节点count -= node.left.val# 进入新的递归self.traversal(node.left, count)# count回溯count += node.left.val# 路径点回溯self.path.pop()# 右节点(同理)if node.right:self.path.append(node.right.val)count -= node.right.valself.traversal(node.right, count)count += node.right.valself.path.pop()return def pathSum(self, root, targetSum):""":type root: TreeNode:type targetSum: int:rtype: List[List[int]]"""if not root:return []# root不是空节点,先放入path中self.path.append(root.val)# 从根节点开始递归,传入参数是已经减掉root值的self.traversal(root, targetSum - root.val)return self.res

 迭代法

迭代在于对于栈的构建。本题采用的是由节点和通向该节点的路径组成的元组,其中路径的类型为由节点值组成的list。

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):def pathSum(self, root, targetSum):""":type root: TreeNode:type targetSum: int:rtype: List[List[int]]"""# 迭代if not root:return []res = []# 注意这个栈的内容:节点和到此节点路径stack = [(root, [root.val])]while stack:# Step 1:取出栈中元素node, path = stack.pop()# 判断当前节点是否是满足条件if not node.left and not node.right and sum(path) == targetSum:res.append(path) # 满足,加入res# Step 2:更新栈中的元素# 左节点if node.left:# 注意这里也需要按照(节点,路径)的元素加入栈stack.append((node.left, path + [node.left.val]))# path 是由值组成的数组,但是可能会出现空值的情况,所以用concatenate不是append# 右节点if node.right:stack.append((node.right, path + [node.right.val]))return res

 106. 从中序与后序遍历序列构造二叉树 - 力扣(LeetCode)​​​​​​

本题在于如何获取中间节点,并按照中间节点划分左右子树的区间。剩下的就是递归左右区间即可。 

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):def buildTree(self, inorder, postorder):""":type inorder: List[int]:type postorder: List[int]:rtype: TreeNode"""# 用后序子树来判断是因为和后续取root逻辑一致if not postorder:return None# 取出root节点的值(后序的最后一位)root_val = postorder[-1]root = TreeNode(root_val)  # 创建根节点# Step 1:在中序数组里找到root的值,作为切割点root_index = inorder.index(root_val)# 全部采用左闭右开区间(循环不变量)# [0, root_index) root_index已经被切走了left_inorder = inorder[:root_index]# [root_index + 1, end]right_inorder = inorder[root_index + 1 :]# Step 2:切割后序数组# 这里使用的是长度# [0, len(左子树))left_postorder = postorder[:len(left_inorder)]# (len(左子树), -1]  :-1是因为root是post的最后一位,已经被取走了right_postorder = postorder[len(left_inorder): -1]# Step 3:递归root.left = self.buildTree(left_inorder, left_postorder)root.right = self.buildTree(right_inorder, right_postorder)return root

特别需要注意的是循环不变量(区间的开闭)。本题使用的是左闭右开。

105. 从前序与中序遍历序列构造二叉树 - 力扣(LeetCode) 

 和上面的一样,但是在前序切片的时候是从1开始,到左子树长度+1处(右端点取不到)。

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):def buildTree(self, preorder, inorder):""":type preorder: List[int]:type inorder: List[int]:rtype: TreeNode"""if not preorder:return Noneroot_val = preorder[0]root = TreeNode(root_val)root_index = inorder.index(root_val)left_inorder = inorder[:root_index]right_inorder = inorder[root_index + 1 : ]left_preorder = preorder[1 : len(left_inorder) + 1]right_preorder = preorder[len(left_inorder) + 1 : ]root.left = self.buildTree(left_preorder, left_inorder)root.right = self.buildTree(right_preorder, right_inorder)return root

第18天完结🎉

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/233350.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【代码随想录】刷题笔记Day36

前言 打球运动量不饱和,不太爽,来刷题爽爽 134. 加油站 - 力扣(LeetCode) 难点在于环形遍历,实际上和最大子序和的思路很像,小于0就从下个位置开始局部最优:当前累加rest[i]的和curSum一旦小…

Oracle的学习心得和知识总结(三十)| OLTP 应用程序的合成工作负载生成器Lauca论文翻译及学习

目录结构 注:提前言明 本文借鉴了以下博主、书籍或网站的内容,其列表如下: 1、参考书籍:《Oracle Database SQL Language Reference》 2、参考书籍:《PostgreSQL中文手册》 3、EDB Postgres Advanced Server User Gui…

Nvidia 驱动安装不完整记录

Nvidia 驱动安装不完整记录 安装 epel, sudo dnf install -y https://dl.fedoraproject.org/pub/epel/epel-releaselatest-8.noarch.rpm安装 gcc-toolset-11-gcc, dnf install gcc-toolset-11-gcc修改 gcc,make,as 为 gcc-tools…

c++ wake_ptr智能指针

转载自c语言中文网 在 C98/03 的基础上,C11 标准新引入了 shared_ptr、unique_ptr 以及 weak_ptr 这 3 个智能指针。其中,shared_ptr 和 unique_ptr 已经在前面章节做了详细地介绍,本节重点讲解 weak_ptr 智能指针的特性和用法。 注意学习 w…

springMVC-数据格式化

1、基本介绍 在一个springmvc项目中,当表单提交数据时,如何对表单提交的数据进行格式的转换呢? 只要是数据进行网络传输都是以字符串的形式,进入内存后才有数据类型。 springmvc在上下文环境内置了一些转换器&#xff0c…

【MyBatis-Plus】常用的内置接口

🥳🥳Welcome Huihuis Code World ! !🥳🥳 接下来看看由辉辉所写的关于MyBatis-Plus的相关操作吧 目录 🥳🥳Welcome Huihuis Code World ! !🥳🥳 1.Service接口 1.1.Save 1.2.Sa…

leetcode每日一题打卡

leetcode每日一题 746.使用最小花费爬楼梯162.寻找峰值1901.寻找峰值Ⅱ 从2023年12月17日开始打卡~持续更新 746.使用最小花费爬楼梯 2023/12/17 代码 解法一 class Solution {public int minCostClimbingStairs(int[] cost) {int n cost.length;int[] dp new int[n1];dp[…

C51--小车——PWM调速

如何进行小车PWM调速: 原理: 全速前进:LeftCon1A 0;LeftCon1B 1; 完全停止:LeftCon1A 0;LeftCon1B 0;单位时间内,例如20ms,有15ms是全速,5m…

【牛客网】编程题:找到无序数组中最小的k个数(146)

[编程题]:找到无序数组中最小的k个数 热度指数:2394时间限制:C/C 2秒,其他语言4秒空间限制:C/C 256M,其他语言512M 算法知识视频讲解 给定一个整型数组arr,找到其中最小的k个数。 输入描述: 输…

Linux常用基本命令操作

目录 一、认识shell 1、什么是shell 2、命令的本质 3、内部命令和外部命令 4、harsh缓存 5、命令执行的过程 6、如果打了一个命令,提示该命令不存在 7、命令提示符 8、Linux系统文件夹 二、Linux常用命令 1、通用Linux命令行格式 2、编辑Linux命令行的辅…

Spring Boot + MinIO 实现文件切片极速上传技术

文章目录 1. 引言2. 文件切片上传简介3. 技术选型3.1 Spring Boot3.2 MinIO 4. 搭建Spring Boot项目5. 集成MinIO5.1 配置MinIO连接信息5.2 MinIO配置类 6. 文件切片上传实现6.1 控制器层6.2 服务层6.3 文件切片上传逻辑 7. 文件合并逻辑8. 页面展示9. 性能优化与拓展9.1 性能优…

qt源码链接C++automic

qaction.cpp source code [qtbase/src/widgets/kernel/qaction.cpp] - Codebrowser C原子变量atomic详解 - 知乎 (zhihu.com)

[C++ 从入门到精通] 15.友元函数、友元类、友元成员函数

📢博客主页:https://loewen.blog.csdn.net📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!📢本文由 丶布布原创,首发于 CSDN,转载注明出处🙉📢现…

统计分析绘图软件 GraphPad Prism 10 mac功能介绍

GraphPad Prism mac是一款专业的统计和绘图软件,主要用于生物医学研究、实验设计和数据分析。 GraphPad Prism mac功能和特点 数据导入和整理:GraphPad Prism 可以导入各种数据格式,并提供直观的界面用于整理、编辑和管理数据。用户可以轻松地…

qsort函数应用

1.引入 我们前面学习了一些常见的排序方法,比如冒泡排序等,但它仅局限于整型的排序,今天我们要介绍一个牛气哄哄的库函数qsort函数,这个函数可就厉害了,能排序任意类型数据,掌握后可谓受益终身,…

PyQt中的冒号(:)

在这段代码中,冒号(:)的使用是类型注解的一种形式,用于显式地指定变量的类型。在Python 3.5及以后的版本中,引入了类型注解的概念,可以在变量名后面使用冒号来注解变量的类型。 例如,在以下代码…

Python 安装第三方模块

要安装三方模块,需要知道模块的名字和pip。 pip来源: Mac、Linux无需安装自带。 Window:勾选了pip和add python.exe to Path 目录 安装Pillow 查看pip版本 命令行安装 查看本地安装库 升级pip 使用Pillow 引入三方库 打开图片 查看图片的信息 …

Metashape 自定义比例尺 / 无POS时如何制作DEM

前言操作步骤 前言 Metashape 自定义比例尺 和 无POS时如何制作DEM,此二者的操作步骤本质上是一样的。 当我们输入的照片没有POS,且没有做像控点的时候,比如我们仅仅拍摄了一个比较小的物体,可能是一瓶饮料或者一个椅子。 那么此…

C++刷题 -- KMP算法

C刷题 – KMP算法 文章目录 C刷题 -- KMP算法1.算法讲解2.算法实现 https://leetcode.cn/problems/find-the-index-of-the-first-occurrence-in-a-string/description/ 1.算法讲解 KMP算法是一种字符串匹配算法,当出现字符串不匹配时,可以记录一部分之…

【>D:\10\Debug\RCa00828(34): fatal error RC1022: expected ‘#endif‘】

1>D:\10\Debug\RCa00828(34): fatal error RC1022: expected ‘#endif’ The error message you’re seeing, fatal error RC1022: expected ‘#endif’, indicates that the resource compiler encountered an issue when processing a resource script file (typically w…