代码随想录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,一经查实,立即删除!

相关文章

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

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

springMVC-数据格式化

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

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[…

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 性能优…

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

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

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算法是一种字符串匹配算法,当出现字符串不匹配时,可以记录一部分之…

【CLion】使用CLion开发STM32

本文主要记录使用CLion开发STM32,并调试相关功能 使用的CLion版本:2023.3.1 CLion嵌入式配置教程:STM32CubeMX项目 |CLion 文档 (jetbrains.com) OpenOCD官网下载:Download OpenOCD for Windows (gnutoolchains.com) GNU ARM工…

lv12 linux 内核移植 10

目录 1 内核概述 1.1 内核与操作系统 1.2 Linux层次结构 1.3 Linux内核特点 2 Linux内核源码结构 2.1 Linux内核源码获取 2.2 源码结构 3 Linux内核移植 3.1 在 Linux 官网下载 Linux 内核源码(这里我们下载 linux-3.14.tar.xz) 3.2 拷贝内核源…

【Spark-ML源码解析】Word2Vec

前言 在阅读源码之前,需要了解Spark机器学习Pipline的概念。 相关阅读:SparkMLlib之Pipeline介绍及其应用 这里比较核心的两个概念是:Transformer和Estimator。 Transformer包括特征转换和学习后的模型两种情况,用来将一个DataFr…

支持向量机 支持向量机概述

支持向量机概述 支持向量机 Support Vector MachineSVM ) 是一类按监督学习 ( supervisedlearning)方式对数据进行二元分类的广义线性分类器 (generalized linear classifier) ,其决策边界是对学习样本求解的最大边距超亚面 (maximum-margin hyperplane)与逻辑回归和…

Unity | Shader基础知识(第七集:案例<让图片和外部颜色叠加显示>)

目录 一、本节介绍 1 上集回顾 2 本节介绍 二、添加图片资源 三、 常用cg数据类型 1 float 2 bool 3 sampler 四、加入图片资源 五、使用图片资源 1 在通道里加入资源 2 使用图片和颜色叠加 2.1 2D纹理采样tex2D 2.2 组合颜色 六、全部代码 七、下集介绍 相关…

26 redis 中 replication/cluster 集群中的主从复制

前言 我们这里首先来看 redis 这边实现比较复杂的 replication集群模式 我们这里主要关注的是 redis 这边的主从同步的相关实现 这边相对比较简单, 我们直接基于 cluster集群模式 进行调试 主从命令同步复制 比如这里 master 是 redis_7002, slave 是 redis_7005 然后 这…

11.HarmonyOS鸿蒙app_page的显示跳转方法

11.HarmonyOS鸿蒙app_page的显示跳转方法&#xff0c;text文本触发点击事件 使用Intent和Operation对象 创建新项目后&#xff0c;再创建secondPageAbility ability_main.xml <?xml version"1.0" encoding"utf-8"?> <DirectionalLayoutxmlns:…

LeetCode(65)LRU 缓存【链表】【中等】

目录 1.题目2.答案3.提交结果截图 链接&#xff1a; LRU 缓存 1.题目 请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。 实现 LRUCache 类&#xff1a; LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存int get(int key) 如果关键字 k…

【ArkTS】路由传参

传参 使用router.pushUrl()&#xff0c;router.push()官方不推荐再使用了。 格式&#xff1a; router.pushUrl({url: 路由地址,params:{参数名&#xff1a;值} )跳转时需要注意路由表中是否包含路由地址。 路由表路径&#xff1a; entry > src > main > resources &g…

Python+pip下载与安装

Hi, I’m Shendi Pythonpip下载与安装 最近有识别图片中物体的需求&#xff0c;于是选用了TensorFlow&#xff0c;在一番考虑下&#xff0c;还是选择直接使用Python。 Python下载安装 直接在搜索引擎搜索Python或通过 https://www.python.org 进入官网 在 Downloads 处点击 Al…

Gin之GORM的表关联查询操作详解

前期工作&#xff1a; 先查看下要操作的两张表&#xff1a; carton carton_cate //关系如下&#xff1a; // 一个章节对应一个动漫&#xff08;一对一&#xff1b;两种方法&#xff1a;belong to&#xff1b;has one&#xff09; // 一个动漫可以对应多个章节&#xff08;一…

Eclipse_01_如何设置代码文件背景颜色为护眼沙绿色

设置方法 Window --> Preference 参考文档 参考文档 1