当前位置: 首页 > news >正文

Leetcod面试经典150题刷题记录 —— 二叉搜索树篇

Leetcod面试经典150题刷题记录-系列
Leetcod面试经典150题刷题记录——数组 / 字符串篇
Leetcod面试经典150题刷题记录 —— 双指针篇
Leetcod面试经典150题刷题记录 —— 矩阵篇
Leetcod面试经典150题刷题记录 —— 滑动窗口篇
Leetcod面试经典150题刷题记录 —— 哈希表篇
Leetcod面试经典150题刷题记录 —— 区间篇
Leetcod面试经典150题刷题记录——栈篇
Leetcod面试经典150题刷题记录——链表篇
Leetcod面试经典150题刷题记录——二叉树篇
Leetcod面试经典150题刷题记录——二叉树层次遍历篇
Leetcod面试经典150题刷题记录——二叉搜索树篇

Leetcod面试经典150题刷题记录 —— 二叉搜索树篇

    • 二叉搜索树性质
    • 1. 二叉搜索树的最小绝对差
      • ==脏乱差==版本
      • ==优雅==版本
    • 2. 二叉搜索树中第K小的元素
    • 3. 验证二叉搜索树
      • 经典错误(从局部性质推断全局性质)
      • 利用第1题的代码(有pre指针的那段)

遇到二叉搜索树(BST)的题目,一旦用了sort()直接挂掉面试,切记!

二叉搜索树性质

二叉搜索树的性质满足:
(1)左节点 > root > 右节点 (局部性质)
(2)左子树所有节点 > root > 右子树所有节点 (全局性质,该性质包括局部性质,所以更重要)
相当部分程序员写起上面的局部性质很容易,写全局性质的判断就容易犯病,不瞒你说,我也是。

1. 二叉搜索树的最小绝对差

题目链接:二叉搜索树的最小绝对差 - leetcode
题目描述:
给你一个二叉搜索树的根节点 root ,返回 树中任意两不同节点值之间的最小差值 。差值是一个正数,其数值等于两值之差的绝对值。
题目归纳:

解题思路:
解法: 验证二叉搜索树 - leetcode官方题解

脏乱差版本

# 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# 返回二叉搜索树中,任意两个不同节点值之间的最小差值
# 性质
# (1)二叉搜索树。题目既然说了,那么肯定要用到该性质
# (2)任意两个不同节点值,强调了任意两个不同节点。但是既然是二叉搜索树了,拿右子树中的节点 - 左子树中的节点肯定不会是答案,所以这里的任意其实是带引号的"任意",不是绝对的"任意",是可以忽略一些情况的"任意"# 以root节点为例,要查找的目标点一定是下面两种情况
# (1)左树的最右节点 = 左树的最大节点 = 中序遍历的前驱pre节点
# (2)右树的最左节点 = 右树的最大节点 = 中序遍历的后继post节点
# 最后递归搜索
class Solution:def getMinDistance(self, root: Optional[TreeNode]) -> int:if not root: return 0# (1)查找左树的最'右'节点 = 左树的最大节点LR = root.leftwhile LR and (LR.left or LR.right):# 有右边找右边,没右边找左边再找右边if LR.right:LR = LR.rightelse:break# (2)查找右树的最'左'节点 = 右树的最大节点RL = root.rightwhile RL and (RL.left or RL.right):if RL.left:RL = RL.leftelse:breakleft_result = 1e9if LR:            left_result = abs(root.val-LR.val)right_result = 1e9if RL:            right_result = abs(root.val-RL.val)return min(left_result, right_result)def getMinimumDifference(self, root: Optional[TreeNode]) -> int:result = 1e9# 逐个遍历queue = deque([root])while queue:size = len(queue)for i in range(size):node = queue.popleft() if node.left: queue.append(node.left)if node.right: queue.append(node.right)dis = self.getMinDistance(node)result = min(result, dis)return result

优雅版本

# 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 __init__(self):self.result = float('inf')self.pre = Nonedef traversal(self, cur):if cur is None:return Noneself.traversal(cur.left)  # 左if self.pre:  # 中self.result = min(self.result, cur.val - self.pre.val)self.pre = cur  # 记录前一个self.traversal(cur.right)  # 右def getMinimumDifference(self, root):self.traversal(root)return self.result

2. 二叉搜索树中第K小的元素

题目链接:二叉搜索树中第K小的元素 - leetcode
题目描述:
给定一个二叉搜索树的根节点 root ,和一个整数 k ,请你设计一个算法查找其中第 k 个最小元素(从 1 开始计数)。
题目归纳:
中序遍历BST成有序数组,然后再找到这个有序数组的第k个元素?NoNoNo。掌握递归转换成迭代的关键思想,即将"函数调用栈"明写在代码里。

解题思路:
解法: 二叉搜索树中第K小的元素 - leetcode官方题解
中序遍历的迭代写法,注意,非递归!

# 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# 这道题掌握两个知识点
# (1)中序遍历的迭代写法。即将函数调用栈明示出来,因为函数调用栈也是个栈,所有的递归写法都是可以转换为迭代版写法的,手动模拟函数调用栈即可。
# (2)二叉搜索树的中序遍历是有序的。class Solution:def kthSmallest(self, root: Optional[TreeNode], k: int) -> int:# 中序遍历,迭代版而非递归stack = []while root or stack:# 相当于递归版写法的左子树遍历while root: # 压栈方向是单一的,沿着二叉树的右上角->左下角方向压栈stack.append(root)root = root.leftroot = stack.pop() # 遇到空就出栈# if root: print(root.val)k -= 1if k == 0:return root.valroot = root.right

3. 验证二叉搜索树

题目链接:验证二叉搜索树 - leetcode
题目描述:
给定一个二叉树的 根节点 root,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。
题目归纳:
右视图 = 右边的侧视图

解题思路:
解法: 验证二叉搜索树 - leetcode官方题解
(1) 从左到右层序遍历。记录层序遍历的最后一个node,即为右视图看到的第一个node。

经典错误(从局部性质推断全局性质)

# 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 isValidBST(self, root: Optional[TreeNode]) -> bool:# 这是一道21年的408考研真题,空节点和叶节点都是二叉搜索树# 注意下面的写法是错误的,原因在于只判断了局部的性质,而忽略了全局的性质if not root: return Trueif not root.left and not root.right: return True# (1)这个时候root肯定存在,左树或许存在,结合root与左树根节点,判断是不是二叉搜索树if root and root.left and root.left.val < root.val:return self.isValidBST(root.left)else:return False# (2)这个时候root肯定存在,右树或许存在,结合root与右树根节点,判断是不是二叉搜索树if root and root.right and root.val < root.right.val:return self.isValidBST(root.right)else:return False

利用第1题的代码(有pre指针的那段)

# 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 __init__(self):self.pre = Nonedef isValidBST(self, root: Optional[TreeNode]) -> bool:if not root:return Trueleft = self.isValidBST(root.left)if self.pre and self.pre.val >= root.val: # __比第1题加了这个判断__return Falseself.pre = root # 要遍历root.right了,这个时候记录pre节点right = self.isValidBST(root.right)return left and right # 两边都要是BST树

相关文章:

Leetcod面试经典150题刷题记录 —— 二叉搜索树篇

Leetcod面试经典150题刷题记录-系列Leetcod面试经典150题刷题记录——数组 / 字符串篇Leetcod面试经典150题刷题记录 —— 双指针篇Leetcod面试经典150题刷题记录 —— 矩阵篇Leetcod面试经典150题刷题记录 —— 滑动窗口篇Leetcod面试经典150题刷题记录 —— 哈希表篇Leetcod面…...

【大数据进阶第三阶段之ClickHouse学习笔记】ClickHouse的简介和使用

1、ClickHouse简介 ClickHouse是一种列式数据库管理系统&#xff08;DBMS&#xff09;&#xff0c;专门用于高性能数据分析和数据仓库应用。它是一个开源的数据库系统&#xff0c;最初由俄罗斯搜索引擎公司Yandex开发&#xff0c;用于满足大规模数据分析和报告的需求。 开源地址…...

Linux下Redis6下载、安装和配置教程-2024年1月5日

Linux下Redis6下载、安装和配置教程-2024年1月5日 一、下载二、安装三、启动四、设置开机自启五、Redis的客户端1.Redis命令行客户端2.windows上的图形化桌面客户端 一、下载 1.Redis的官方下载&#xff1a;https://redis.io/download/ 2.网盘下载&#xff1a; 链接&#xff…...

Java后端开发——Ajax、jQuery和JSON

Java后端开发——Ajax、jQuery和JSON 概述 Ajax全称是Asynchronous Javascript and XML&#xff0c;即异步的JavaScript和 XML。Ajax是一种Web应用技术&#xff0c;该技术是在JavaScript、DOM、服务器配合下&#xff0c;实现浏览器向服务器发送异步请求。 Ajax异步请求方式不…...

ssm基于Vue的戏剧推广网站论文

摘 要 如今社会上各行各业&#xff0c;都喜欢用自己行业的专属软件工作&#xff0c;互联网发展到这个时候&#xff0c;人们已经发现离不开了互联网。新技术的产生&#xff0c;往往能解决一些老技术的弊端问题。因为传统戏剧推广信息管理难度大&#xff0c;容错率低&#xff0c…...

安卓adb

目录 如何开启 ADB 注意事项 如何使用 ADB ADB 能干什么 ADB&#xff08;Android Debug Bridge&#xff09;是一个多功能命令工具&#xff0c;它可以允许你与 Android 设备进行通信。它提供了多种设备权限&#xff0c;包括安装和调试应用&#xff0c;以及访问设备上未通过…...

【数位dp】【动态规划】C++算法:233.数字 1 的个数

作者推荐 【动态规划】C算法312 戳气球 本文涉及的基础知识点 动态规划 数位dp LeetCode:233数字 1 的个数 给定一个整数 n&#xff0c;计算所有小于等于 n 的非负整数中数字 1 出现的个数。 示例 1&#xff1a; 输入&#xff1a;n 13 输出&#xff1a;6 示例 2&#xff…...

docker (portainer 安装nginx)

汉化版步骤可以参考&#xff1a;写文章-CSDN创作中心https://mp.csdn.net/mp_blog/creation/editor/135258056 一、创建容器 二、配置端口&#xff0c;以及容器卷挂载 挂载目录配置&#xff1a;(下方截图的目录如下&#xff0c;docker 改为 mydocker&#xff0c;用docker作为根…...

10个linux文件管理命令

1. ls – 列出目录内容 ls可能是每个Linux用户在其终端中键入的第一个命令。它允许您列出您想要的目录的内容&#xff08;默认情况下是当前目录&#xff09;&#xff0c;包括文件和其他嵌套目录。 它有很多选择&#xff0c;所以最好使用 --help 来获得一些帮助。此标志返回所…...

实战:使用docker容器化服务与文件挂载-2

接着上文&#xff0c;演示Elasticsearch 和 Kibana 的安装&#xff0c;并讲解文件挂载 Elasticsearch of Docker &#xff08;Kibana&#xff09; 1、Elasticsearch 安装 ElasticSearch 使用 Docker 安装&#xff1a;https://www.yuque.com/zhangshuaiyin/guli-mall/dwrp5b 1.…...

联合union

//————联合&#xff1a;union 1.联合的定义 联合也是一种特殊的自定义类型 #include<stdio.h> union Un//Un为联合标签 { int a; char c; }; struct St { int a; int b; }; int main() { union Un u; printf("%d\n",sizeof(u));//…...

如何在 Umi /Umi 4.0 中配置自动删除 console.log 语句?

背景&#xff0c;开发时需要console.log 日志&#xff0c;再生产、uat 、sit不想看到日志打印信息 方案1、代码规范eslint校验"no-console": true, //console.log 方案2、bable 插件 babel-plugin-transform-remove-console 配置在.umirx.ts/js中 export default…...

(生物信息学)R语言绘图初-中-高级——3-10分文章必备——饼图(初级)

生物信息学文章的发表要求除了思路和热点以外,图片绘制是否精美也是十分重要的,本专栏为(生物信息学)R语言绘图初-中-高级——3-10分文章必备,主要通过大量文献,总结3-10分文章中高频出现的各种图片,并给大家提供图片复现的R语言代码,及图片识读。 本专栏将向大家介绍…...

AI ppt生成器 Tome

介绍 一款 AI 驱动的 PPT/幻灯片内容辅助生成工具。只需要输入一个标题或者一段特定的描述&#xff0c;AI 便会自动生成一套包括标题、大纲、内容、配图的完整 PPT。 Tome平台只需要用户输入一句话&#xff0c;就可以自动生成完整的PPT&#xff0c;包括文字和图片。功能非常强…...

Linux与Windows下追踪网络路由:traceroute、tracepath与tracert命令详解

简介 在进行网络诊断或排查问题时&#xff0c;了解数据包从源主机到目标主机之间的具体传输路径至关重要。Linux系统提供了traceroute和tracepath工具来实时显示链路路径信息&#xff0c;而Windows则使用了tracert命令实现相同的功能。本文将详细介绍这三个命令的用法及其在不…...

图解JVM (及一些垃圾回收\GC相关面试题 持续更新)

垃圾回收&#xff0c;顾名思义就是释放垃圾占用的空间&#xff0c;从而提升程序性能&#xff0c;防止内存泄露。当一个对象不再被需要时&#xff0c;该对象就需要被回收并释放空间。 Java 内存运行时数据区域包括程序计数器、虚拟机栈、本地方法栈、堆等区域。其中&#xff0c;…...

linux 系统安全及应用

一、账号安全基本措施 1.系统账号清理 1.将用户设置为无法登录 /sbin/nologin shell——/sbin/nologin却比较特殊&#xff0c;所谓“无法登陆”指的仅是这个用户无法使用bash或其他shell来登陆系统而已&#xff0c;并不是说这个账号就无法使用系统资源。举例来说&#xff0c;…...

如何查看崩溃日志

​ 目录 描述 思路 查看ipa包崩溃日志 简单查看手机崩溃信息几种方式 方式1:手机设置查看崩溃日志 方式2: Xocde工具 方式3: 第三方软件克魔助手 环境配置 实时日志 奔溃日志分析 方式四&#xff1a;控制台资源库 线上崩溃日志 线上监听crash的几种方式 方式1: 三…...

使用HttpSession和过滤器实现一个简单的用户登录认证的功能

这篇文章分享一下怎么通过session结合过滤器来实现控制登录访问的功能&#xff0c;涉及的代码非常简单&#xff0c;通过session保存用户登录的信息&#xff0c;如果没有用户登录的话&#xff0c;会在过滤器中处理&#xff0c;重定向回登录页面。 创建一个springboot项目&#…...

SEO全自动发布外链工具源码系统:自动增加权重 附带完整的搭建安装教程

SEO全自动发布外链工具是一款基于PHP和MySQL开发的外链发布工具。它通过自动化流程&#xff0c;帮助站长快速、有效地发布外链&#xff0c;提高网站的权重和排名。该工具支持多种外链发布平台&#xff0c;如论坛、博客、分类信息等&#xff0c;可自定义发布内容和格式&#xff…...

Admin.Net中的消息通信SignalR解释

定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...

深入理解JavaScript设计模式之单例模式

目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式&#xff08;Singleton Pattern&#…...

对WWDC 2025 Keynote 内容的预测

借助我们以往对苹果公司发展路径的深入研究经验&#xff0c;以及大语言模型的分析能力&#xff0c;我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际&#xff0c;我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测&#xff0c;聊作存档。等到明…...

Redis数据倾斜问题解决

Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中&#xff0c;部分节点存储的数据量或访问量远高于其他节点&#xff0c;导致这些节点负载过高&#xff0c;影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...

在Ubuntu24上采用Wine打开SourceInsight

1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...

C++.OpenGL (14/64)多光源(Multiple Lights)

多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...

C/C++ 中附加包含目录、附加库目录与附加依赖项详解

在 C/C 编程的编译和链接过程中&#xff0c;附加包含目录、附加库目录和附加依赖项是三个至关重要的设置&#xff0c;它们相互配合&#xff0c;确保程序能够正确引用外部资源并顺利构建。虽然在学习过程中&#xff0c;这些概念容易让人混淆&#xff0c;但深入理解它们的作用和联…...

【JVM面试篇】高频八股汇总——类加载和类加载器

目录 1. 讲一下类加载过程&#xff1f; 2. Java创建对象的过程&#xff1f; 3. 对象的生命周期&#xff1f; 4. 类加载器有哪些&#xff1f; 5. 双亲委派模型的作用&#xff08;好处&#xff09;&#xff1f; 6. 讲一下类的加载和双亲委派原则&#xff1f; 7. 双亲委派模…...

Selenium常用函数介绍

目录 一&#xff0c;元素定位 1.1 cssSeector 1.2 xpath 二&#xff0c;操作测试对象 三&#xff0c;窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四&#xff0c;弹窗 五&#xff0c;等待 六&#xff0c;导航 七&#xff0c;文件上传 …...

搭建DNS域名解析服务器(正向解析资源文件)

正向解析资源文件 1&#xff09;准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2&#xff09;服务端安装软件&#xff1a;bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...