算法打卡day17

news/2024/5/15 20:51:33/文章来源:https://blog.csdn.net/wenxiaohai123/article/details/137046838

今日任务:

1)654.最大二叉树

2)617.合并二叉树

3)700.二叉搜索树中的搜索

4)98.证二叉搜索树

654.最大二叉树

题目链接:654. 最大二叉树 - 力扣(LeetCode)

给定一个不含重复元素的整数数组。一个以此数组构建的最大二叉树定义如下:
1.二叉树的根是数组中的最大元素。
2.左子树是通过数组中最大值左边部分构造出的最大二叉树。
3.右子树是通过数组中最大值右边部分构造出的最大二叉树。


通过给定的数组构建最大二叉树,并且输出这个树的根节点。

输入:[3,2,1,6,0,5]
输出:返回下面这棵树的根节点:
[6,3,5,None,2,0,None,None,1]

文章讲解:代码随想录 (programmercarl.com)

视频讲解:又是构造二叉树,又有很多坑!| LeetCode:654.最大二叉树哔哩哔哩bilibili

思路:

很明显这题采用深度优先遍历算法(DFS)中的前序遍历

1)首先找出列表中的最大数作为根节点

2)最大数左边列表作为左子树,最大数右边列表作为右子树。

3)将左右列表作为新列表,重复1)-2)步

4)返回根节点

这里第三步就是开始递归了,那我们需要明确递归函数的参数与返回值,明确递归函数的终止条件,递归函数的单层逻辑

终止条件:当列表的大小为1时,也就是列表中只有一个树,直接将这个树作为当前递归中的根节点即可返回当前节点(从整体上看,起始这个节点应该是一个叶子节点)

单层递归逻辑:遍历列表找出列表最大值,并从最大值拆分成左右子树区间

递归函数参数与返回值:参数肯定要传入区间,返回值返回当前递归层中的根节点

# Definition for a binary tree node.
class TreeNode:def __init__(self, val=0, left=None, right=None):self.val = valself.left = leftself.right = rightclass Solution:def constructMaximumBinaryTree(self, nums: list[int]) -> Optional[TreeNode]:if not nums:returnnum_size = len(nums)if num_size == 1:return TreeNode(nums[0])# 找最大值索引max_index = 0for i in range(num_size):if nums[i] > nums[max_index]:max_index = inode = TreeNode(nums[max_index])  # 中node.left = self.constructMaximumBinaryTree(nums[:max_index])  # 左node.right = self.constructMaximumBinaryTree(nums[max_index + 1:])  # 右return node

根据上面的思路,我写出来最直白的代码就是这样,比较好理解,还有一些改进的空间。

我是用力扣上给出的这个函数作为递归函数,所以其传参与返回值就固定了。而我们传参时使用切片,会浪费内存开销。我们可以重新定义一个递归函数,传参改为传入列表起始和终止,这样我们操作的就是一个列表,而不是每次递归重新创建列表。

# Definition for a binary tree node.
class TreeNode:def __init__(self, val=0, left=None, right=None):self.val = valself.left = leftself.right = right# 改进,不使用切片,会额外浪费内存开销,采用传入列表起始终止索引
class Solution2:def constructMaximumBinaryTree(self, nums: list[int]) -> Optional[TreeNode]:if not nums:returnreturn self.traversal(nums, 0, len(nums))def traversal(self, nums: list[int], left: int, right: int):if left >= right:returnmax_index = leftfor i in range(left + 1, right):if nums[i] > nums[max_index]:max_index = inode = TreeNode(nums[max_index])node.left = self.traversal(nums, left, max_index)node.right = self.traversal(nums, max_index + 1, right)return node

617.合并二叉树

题目链接:617. 合并二叉树 - 力扣(LeetCode)

给定两个二叉树,想象当你将它们中的一个覆盖到另一个上时,两个二叉树的一些节点便会重叠。
你需要将他们合并为一个新的二叉树。合并的规则是如果两个节点重叠,那么将他们的值相加作为节点合并后的新值,否则不为 NULL 的节点将直接作为新二叉树的节点。


示例 1:
输入:root1 = [1,3,2,5], root2 = [2,1,3,null,4,null,7]
输出:[3,4,5,5,4,null,7]

示例 2:
输入:root1 = [1], root2 = [1,2]
输出:[2,2]

文章讲解:代码随想录 (programmercarl.com)

视频讲解:一起操作两个二叉树?有点懵!| LeetCode:617.合并二叉树哔哩哔哩bilibili

思路:

我们可以采用深度优先遍历(DFS)中的前序遍历,

1)两棵树同时开始遍历,判断两棵树根节点是否为空,若一个为空,则返回另一个,连个都为空,也是返回空

2)当两个节点不为空时,则相加,我们可以创建新树记录,也可以在原树上修改

3)重复1)-2),继续比较两个树根节点的左节点,右节点

4)返回合并后的根节点

递归的终止:但凡有一个节点为空, 就立刻返回另外一个. 如果另外一个也为None就直接返回None.

单层递归逻辑:当两个节点均不为空时,继续比较其左右节点

递归函数的参数和返回值:用力扣给的函数作为递归函数,参数和返回值已经固定了

class TreeNode:def __init__(self, val=0, left=None, right=None):self.val = valself.left = leftself.right = right
class Solution:def mergeTrees(self, root1: TreeNode, root2: TreeNode) -> TreeNode:# 递归终止条件:#  但凡有一个节点为空, 就立刻返回另外一个. 如果另外一个也为None就直接返回None.if not root1:return root2if not root2:return root1# 上面的递归终止条件保证了代码执行到这里root1, root2都非空.root1.val += root2.val  # 中root1.left = self.mergeTrees(root1.left, root2.left)  # 左root1.right = self.mergeTrees(root1.right, root2.right)  # 右return root1  # ⚠️ 注意: 本题我们重复使用了题目给出的节点而不是创建新节点. 节省时间, 空间.

700.二叉搜索树中的搜索

题目链接:700. 二叉搜索树中的搜索 - 力扣(LeetCode)

给定二叉搜索树(BST)的根节点 root 和一个整数值 val。
你需要在 BST 中找到节点值等于 val 的节点。 返回以该节点为根的子树。 如果节点不存在,则返回 null 。

一个二叉搜索树具有如下特征:

  • 节点的左子树只包含小于当前节点的数。
  • 节点的右子树只包含大于当前节点的数。
  • 所有左子树和右子树自身必须也是二叉搜索树。

示例 1:
输入:root = [4,2,7,1,3], val = 2
输出:[2,1,3]

示例 2:
输入:root = [4,2,7,1,3], val = 5
输出:[]

文章讲解:代码随想录 (programmercarl.com)

视频讲解:不愧是搜索树,这次搜索有方向了!| LeetCode:700.二叉搜索树中的搜索哔哩哔哩bilibili

思路:

根据搜索二叉树的定义,这题比较好做,我们只需要从上到下遍历

当目标值等于当前节点值,我们则直接返回这个节点即可

当目标值大于当前节点值,我们则往右子树找

当目标值小于当前节点值,我们则往左子树找

class TreeNode:def __init__(self, val=0, left=None, right=None):self.val = valself.left = leftself.right = rightclass Solution:def searchBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:# 终止if not root or root.val == val:return rootif root.val>val:return self.searchBST(root.left,val)if root.val<val:return self.searchBST(root.right,val)

这题也可以使用迭代法实现深度优先遍历,因为搜索树结构的特殊性(中序遍历节点的有序性),不需要回溯。代码如下:

class TreeNode:def __init__(self, val=0, left=None, right=None):self.val = valself.left = leftself.right = rightclass Solution:def searchBST(self, root: TreeNode, val: int) -> TreeNode:while root:if val < root.val:root = root.leftelif val > root.val:root = root.rightelse:return rootreturn None

感想:不同二叉树都有其结构特性,要多熟悉其结构特性

98.验证二叉搜索树

题目链接:98. 验证二叉搜索树 - 力扣(LeetCode)

文章讲解:代码随想录 (programmercarl.com)

视频讲解:你对二叉搜索树了解的还不够! | LeetCode:98.验证二叉搜索树哔哩哔哩bilibili

思路:

如果给一个搜索二叉树,我们中序遍历出来的顺序是一个单调递增的

中序遍历:234567

所以最简单直接的方法是,将二叉树采用中序遍历出来,用数组存储,然后遍历数组后一位是否大于前一位。

这里我们可以不用数组,在遍历的过程中就将上一个节点用变量存储起来,当遍历到下一个节点时,比较其是否大于上一个节点即可。如果小直接返回False,如果大则继续

class TreeNode:def __init__(self, val=0, left=None, right=None):self.val = valself.left = leftself.right = rightclass Solution:def __init__(self):self.max_val = float('-inf')def isValidBST(self, root: Optional[TreeNode]) -> bool:if not root:return True# 左left = self.isValidBST(root.left)# 中if root.val > self.max_val:self.max_val = root.valelse:return False# 右right = self.isValidBST(root.right)return left and right

这里存储上一个节点的变量max_val,我们设为了float('-inf'),没有用int('-inf'),是因为测试案例中存在节点的值为int('-inf'),那我们就不能拿这个去比较,所以我采用了float('-inf'),但是这样也有一个问题,当测试案例中出现最小值为float('-inf'),我们这个代码也会报错,所以接下来我们做了一点调整

# 改进
class Solution2:def __init__(self):self.pre = Nonedef isValidBST(self, root: Optional[TreeNode]) -> bool:if not root:return True# 左left = self.isValidBST(root.left)# 中if self.pre is not None and self.pre >= root.val:return Falseelse:self.pre = root.val# 右right = self.isValidBST(root.right)return left and right

这里有坑,第一反应判空时,if self.pre即表示其不为空,但是我们这self.pre存放的是数值!!当self.pre=0时也会跳过

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

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

相关文章

计算机网络数据链路层知识总结

物理层知识总结传送门 计算机网络物理层知识点总结-CSDN博客 功能 功能概述 一些基本概念 结点:主机、路由器链路﹔网络中两个结点之间的物理通道&#xff0c;链路的传输介质主要有双绞线、光纤和微波。分为有线链路、无线链路。数据链路︰网络中两个结点之间的逻辑通道&a…

HarmonyOS实战开发-如何实现一个自定义抽奖圆形转盘

介绍 本篇Codelab是基于画布组件、显式动画&#xff0c;实现的一个自定义抽奖圆形转盘。包含如下功能&#xff1a; 通过画布组件Canvas&#xff0c;画出抽奖圆形转盘。通过显式动画启动抽奖功能。通过自定义弹窗弹出抽中的奖品。 相关概念 Stack组件&#xff1a;堆叠容器&am…

STM32第十节(中级篇):EXTI(第一节)——EXTI功能框图及初始化结构体讲解(包括STM32中断应用总结)

目录 前言 STM32第十节&#xff08;中级篇&#xff09;&#xff1a;EXTI&#xff08;第一节&#xff09;——EXTI功能框图及初始化结构体讲解&#xff08;包括STM32中断应用总结&#xff09; EXTI功能框图 EXTI初始化结构体讲解 STM32中断应用总结 NVIC介绍 优先级 优先…

后端常问面经之并发

volatile 关键字 volatile关键字是如何保证内存可见性的&#xff1f;底层是怎么实现的&#xff1f; "观察加入volatile关键字和没有加入volatile关键字时所生成的汇编代码发现&#xff0c;加入volatile关键字时&#xff0c;会多出一个lock前缀指令”lock前缀指令实际上相…

Radash一款JavaScript最新的实用工具库,Lodash的平替!

文章目录 Lodash 的痛点进入正题--Radash特点 举例几个常用的api 一说lodash应该大部分前端同学都知道吧&#xff0c;陪伴我们好多年的JavaScript工具库&#xff0c;但是自从 ES6 出现后就慢慢退出前端人的视线&#xff0c;能ES6写的代码绝对不会用Lodash&#xff0c;也不是完全…

C#预处理器指令(巨细版)

文章目录 一、预处理器指令的基本概念二、预处理器指令的基本规则三、C# 预处理器指令详解3.1 #define 和 #undef3.2 #if、#else、#elif 和 #endif3.3 #line3.4 #error 和 #warning3.5 #region 和 #endregion 四、高级应用&#xff1a;预处理器指令的最佳实践4.1 条件编译的最佳…

PS从入门到精通视频各类教程整理全集,包含素材、作业等复发(2)

PS从入门到精通视频各类教程整理全集&#xff0c;包含素材、作业等 最新PS以及插件合集&#xff0c;可在我以往文章中找到 由于阿里云盘有分享次受限制和文件大小限制&#xff0c;今天先分享到这里&#xff0c;后续持续更新 初级教程素材 等文件 https://www.alipan.com/s/fC…

【edge浏览器无法登录某些网站,以及迅雷插件无法生效的解决办法】

edge浏览器无法登录某些网站&#xff0c;以及迅雷插件无法生效的解决办法 edge浏览器无法登录某些网站&#xff0c;但chrome浏览器可以登录浏览器插件无法使用&#xff0c;比如迅雷如果重装插件重装浏览器重装迅雷后仍然出现问题 edge浏览器无法登录某些网站&#xff0c;但chro…

【生活】如何学习理财

文章目录 1. 了解基本财务知识2. 制定预算4321理财法则 3. 学习投资知识股票债券基金外汇房地产 4. 了解保险知识人身保险人寿保险健康保险意外伤害保险 财产保险财产损失保险责任保险信用保险 5. 寻求专业建议6. 持续学习和实践参考 首先我们想文心一言提问&#xff1a;如何学…

二十二、软考-系统架构设计师笔记-真题解析-2018年真题

软考-系统架构设计师-2018年上午选择题真题 考试时间 8:30 ~ 11:00 150分钟 1.在磁盘调度管理中&#xff0c;应先进行移臂调度&#xff0c;再进行旋转调度。假设磁盘移动臂位于21号柱面上&#xff0c;进程的请求序列如下表所示。如果采用最短移臂调度算法&#xff0c;那么系统…

EXCEL VBA根据表数据写入数据库中

EXCEL VBA根据表数据写入数据库中 Option Explicithttps://club.excelhome.net/thread-1687531-1-1.htmlSub UpdateAccess()Const adStateOpen 1Dim vData, i As Variant, j As LongDim AccessTable As String, ExcelTable As String, ExcelFile As String, AccessFile As Str…

力扣.21. 合并两个有序链表(c语言)

题目描述&#xff1a; 解题方法&#xff1a; struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) {if(!list1)return list2;if(!list2)return list1;struct ListNode* l1list1,*l2list2,*newheadNULL,*newtailNULL;while(l1&&l2){if(l…

[羊城杯 2020]EasySer

[羊城杯 2020]EasySer 进入页面&#xff0c;发现是ubuntuapache2&#xff0c;但是好像没啥用 尝试访问/robots.txt&#xff0c;得到 访问/star1.php/&#xff0c;查看源码&#xff0c;得到提示 一看就知道是ssrf&#xff0c;使用http://127.0.0.1/ser.php&#xff0c;得到…

uniapp 微信小程序 前端登录流程

步骤&#xff1a; 1. 从uniapp button 中通过 getphonenumber 获取 encryptedData、iv 2. 调用 uni.login() 获取 wx code&#xff0c;然后用wx code 获取session_key、unionid 等信息&#xff08;老用户直接用union_id调后端登录接口即可&#xff0c;新用户需进行加密解密获…

EXCEL通过VBA字典快速分类求和

EXCEL通过VBA字典快速分类求和 汇总截图 Option ExplicitOption Explicit Sub answer3() Dim wb As Workbook Dim sht As Worksheet Set wb ThisWorkbook Set sht wb.Worksheets(2) Dim ss1 As Integer Dim ss2 As Integer Dim i As Integer Dim j As Integer j 1Dim aa()…

智慧旅游中数据可视化的革新作用

在数字化浪潮席卷全球的今天&#xff0c;数据可视化技术已成为链接信息与用户的重要桥梁&#xff0c;尤其在智慧旅游领域&#xff0c;它的作用更是日益凸显。随着智慧旅游的概念越来越被重视&#xff0c;数据可视化成为其提供高效、直观服务的关键手段之一。本文将探讨数据可视…

C#使用SQLite(含加密)保姆级教程

C#使用SQLite 文章目录 C#使用SQLite涉及框架及库复制runtimes创建加密SQLite文件生成连接字串执行SQL生成表SQLiteConnectionFactory.cs 代码结构最后 涉及框架及库 自己在NuGet管理器里面安装即可 Chloe.SQLite&#xff1a;ORM框架Microsoft.Data.Sqlite.Core&#xff1a;驱…

数据结构学习——链表面试题

1. 删除链表中等于给定值 val 的所有结点。 203. 移除链表元素 - 力扣&#xff08;LeetCode&#xff09; 方法一&#xff1a; struct ListNode* removeElements(struct ListNode* head, int val) {struct ListNode* prevNULL;struct ListNode* curhead;while(cur){if(cur-&…

零基础入门转录组数据分析——绘制差异火山图

零基础入门转录组数据分析——绘制差异火山图 差异分析的火山图(Volcano Plot)在生物信息学数据分析中,特别是在基因表达差异分析中,是一个非常直观和有用的工具。 本教程将从导入的数据结构开始,一步步带大家在R中绘制好看的火山图,最后对火山图进行解读,确保读者理解…

修复系统中缺失的VCRUNTIME140.dll文件DLL错误问题

在计算机编程中&#xff0c;动态链接库&#xff08;DLL&#xff09;是一种重要的组件&#xff0c;它提供了许多功能和资源供程序使用。其中&#xff0c;VCRuntime140.dll是Visual C Redistributable Packages的一部分&#xff0c;它包含了运行C应用程序所需的运行时库。本文将详…