python coding with ChatGPT 打卡第20天| 二叉搜索树:搜索、验证、最小绝对差、众数

相关推荐
python coding with ChatGPT 打卡第12天| 二叉树:理论基础
python coding with ChatGPT 打卡第13天| 二叉树的深度优先遍历
python coding with ChatGPT 打卡第14天| 二叉树的广度优先遍历
python coding with ChatGPT 打卡第15天| 二叉树:翻转二叉树、对称二叉树
python coding with ChatGPT 打卡第16天| 二叉树:完全二叉树、平衡二叉树、二叉树的所有路径、左叶子之和
python coding with ChatGPT 打卡第17天| 二叉树:找树左下角的值、路径总和
python coding with ChatGPT 打卡第18天| 二叉树:从中序与后序遍历序列构造二叉树、最大二叉树
python coding with ChatGPT 打卡第19天| 二叉树:合并二叉树

二叉搜索树中的搜索

Key Points

1.二叉搜索树是一个有序树:

- 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
- 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
- 它的左、右子树也分别为二叉搜索树

2.二叉搜索树的迭代
一提到二叉树遍历的迭代法,可能立刻想起使用栈来模拟深度遍历,使用队列来模拟广度遍历。

对于二叉搜索树可就不一样了,因为二叉搜索树的特殊性,也就是节点的有序性,可以不使用辅助栈或者队列就可以写出迭代法

对于一般二叉树,递归过程中还有回溯的过程,例如走一个左方向的分支走到头了,那么要调头,在走右分支。

对于二叉搜索树,不需要回溯的过程,因为节点的有序性就帮我们确定了搜索的方向

相关题目

700. 二叉搜索树中的搜索

视频讲解

这次搜索有方向了

重点分析

方法一:
递归法

def searchBST(root, val):if not root:return Noneif root.val > val:return searchBST(root.left, val)if root.val < val:return searchBST(root.right, val)return root

方法二:
迭代法

def searchBST(root, val):current = rootwhile current:if current.val > val:current = current.leftcontinueif current.val < val:current = current.rightcontinueelse:breakreturn current

验证二叉搜索树

Key Points

中序遍历下,输出的二叉搜索树节点的数值是升序序列。

相关题目

98. 验证二叉搜索树

视频讲解

你对二叉搜索树的了解还不够

重点分析

方法一:
不使用有序序列
在这里插入图片描述
我们可以定义一个辅助函数checkBST,它接收四个参数:当前节点node、minVal(当前节点值允许的最小值)、maxVal(当前节点值允许的最大值)、以及初始的根节点root。这个辅助函数将帮助我们递归地验证每个子树,同时保持跟踪允许的值的范围。

def checkBST(node, minVal, maxVal):if not node:return Trueif node.val <= minVal or node.val >= maxVal:return Falsereturn checkBST(node.left, minVal, node.val) and checkBST(node.right, node.val, maxVal)def isValidBST(root):return checkBST(root, float('-inf'), float('inf'))

这段代码使用了一个嵌套的辅助函数checkBST来递归地验证每个节点是否符合二叉搜索树的条件,它通过维护每个节点的值允许的最小值和最大值来实现。这种方法能够确保所有的左子树节点都小于它的父节点,并且所有的右子树节点都大于它的父节点,同时还考虑了所有祖先节点的约束条件。

方法二:
使用有序序列 + 双指针 递归法
在这里插入图片描述

class Solution:def __init__(self):self.pre = None  # 用来记录前一个节点def isValidBST(self, root):if root is None:return Trueleft = self.isValidBST(root.left)if self.pre is not None and self.pre.val >= root.val:return Falseself.pre = root  # 记录前一个节点right = self.isValidBST(root.right)return left and right

方法三:
使用有序序列 + 双指针 迭代法

在这里插入图片描述

def isValidBST(root):stack = []prev = Nonewhile stack or root:# 遍历到最左while root:stack.append(root)root = root.left# 访问节点root = stack.pop()# 检查当前节点是否大于前一个节点if prev and root.val <= prev.val:return Falseprev = root# 转向右子树root = root.rightreturn True

二叉搜索树的最小绝对差

Key Points

  1. 在升序数组中,任意两个相邻元素的差值最小
  2. 1)暴力法:先中序遍历得到升序数列,再遍历数组求最小差值;
    2)简化法:遍历的过程中使用双指针

相关题目

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

视频讲解

二叉搜索树中的双指针遍历

重点分析

方法一:
递归法

class Solution(object):def __init__(self):self.pre = None   self.diff = float('inf')  # 只使用一次,所以是全局变量def getMinimumDifference(self, root):self.in_traversal(root)return self.diffdef in_traversal(self, root):if not root:returnself.in_traversal(root.left)if self.pre:self.diff = min(root.val - self.pre.val, self.diff)self.pre = rootself.in_traversal(root.right)return

方法二:
迭代法 + 暴力

def getMinimumDifference(root):stack_record = []current = rootres = []while stack_record or current:while current:stack_record.append(current)current = current.leftcurrent = stack_record.pop()res.append(current.val)# 左中都处理完了,转向右current = current.righti = 0j = i+1diff = res[j] - res[i]while j < len(res):diff = min(res[j] - res[i], diff)i += 1j += 1return diff

注:LeetCode题目中说明节点至少为两个,所以使用双指针不用讨论数组长度

方法三:
迭代法+简化

def getMinimumDifference(root):stack_record = []current = rootdiff = float('inf')pre = Nonewhile stack_record or current:while current:stack_record.append(current)current = current.leftcurrent = stack_record.pop()if pre is None:   # if not pre 不行,警惕0的情况pre = current.valelse:diff = min(current.val-pre, diff)pre = current.valcurrent = current.rightreturn diff

二叉搜索树中的众数

Key Points

首先如果不是二叉搜索树的话,应该怎么解题,是二叉搜索树,又应该如何解题,两种方式做一个比较,可以加深大家对二叉树的理解。

  1. 如果不是二叉搜索树,最直观的方法一定是把这个树都遍历了,用map统计频率,把频率排个序,最后取前面高频的元素的集合。
  2. 对于二叉搜索树,遍历有序数组的元素出现频率,从头遍历,那么一定是相邻两个元素作比较,然后就把出现频率最高的元素输出就可以了。

相关题目

501. 二叉搜索树中的众数

视频讲解

双指针+代码技巧

重点分析

方法一:
暴力法 哈希表(迭代)

def findMode(root):res = []stack_record = []current = rootwhile stack_record or current:while current:stack_record.append(current)current = current.leftcurrent = stack_record.pop()res.append(current.val)current = current.rightrecord = {}for x in res:record[x] = record.get(x, 0) + 1record_sort = sorted(record.items(), key=lambda x:x[1], reverse=True)results = []max_val = record_sort[0][1]for x in record_sort:if x[1] == max_val:results.append(x[0])else:breakreturn results

方法二:
遍历两遍 双指针 (迭代法)

def findMode(root):res = []stack_record = []current = rootwhile stack_record or current:while current:stack_record.append(current)current = current.leftcurrent = stack_record.pop()res.append(current.val)current = current.rightpre = Nonecount = 0max_count = 0results = []for x in res:if pre is not None:if pre == x:count +=1else:count = 1else:count = 1pre = xif count == max_count:results.append(x)elif count > max_count:max_count = countresults = [x]return results

方法三:
遍历一遍 迭代法

def findMode(root):res = []pre = Nonemax_count = 0count = 0stack_record = []current = rootwhile stack_record or current:while current:stack_record.append(current)current = current.leftcurrent = stack_record.pop()if pre:if current.val == pre.val:count += 1else:count = 1else:count = 1pre = currentif count == max_count:res.append(current.val)elif count > max_count:max_count = countres = [current.val]current = current.rightreturn res

方法四:
遍历一遍 递归法

class Solution:def __init__(self):self.pre = Noneself.res = []self.max_count = 0self.count = 0def in_traversal(self, root):if not root:returnself.in_traversal(root.left)if self.pre:if root.val == self.pre.val:self.count += 1else:self.count = 1else:self.count = 1self.pre = rootif self.count == self.max_count:self.res.append(root.val)elif self.count > self.max_count:self.max_count = self.countself.res = [root.val]self.in_traversal(root.right)returndef findMode(self, root):self.in_traversal(root)return self.res

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

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

相关文章

数据安全之认识数据资产管理平台

文章目录 一、什么是数据资产二、什么是数据资产管理平台1、什么是数据资产管理平台2、为什么需要数据资产管理平台 三、数据资产管理平台的主要功能四、数据资产管理平台的工作原理五、数据资产管理平台的应用场景六、安全资产管理平台与数据资产管理平台的区别与关系1、安全资…

Bert基础(一)--自注意力机制

1、简介 当下最先进的深度学习架构之一&#xff0c;Transformer被广泛应用于自然语言处理领域。它不单替代了以前流行的循环神经网络(recurrent neural network, RNN)和长短期记忆(long short-term memory, LSTM)网络&#xff0c;并且以它为基础衍生出了诸如BERT、GPT-3、T5等…

从入门到精通:AI绘画与修图实战指南

&#x1f482; 个人网站:【 海拥】【神级代码资源网站】【办公神器】&#x1f91f; 基于Web端打造的&#xff1a;&#x1f449;轻量化工具创作平台&#x1f485; 想寻找共同学习交流的小伙伴&#xff0c;请点击【全栈技术交流群】 在这篇文章中&#xff0c;我们将深入探讨如何利…

一篇博客教会你让Spring扫描自定义注解

文章目录 自定义注解使用注解Spring 管理其他 Spring 支持扫描开发人员自定义的注解&#xff0c;从而使开发人员更加灵活方便地使用注解。 自定义注解 我们可以在我们自定义的注解上添加 Spring 的 Component 注解&#xff0c;这样 Spring 框架就会将我们自定义的注解标识的类…

Avalonia 初学笔记(1):环境配置

文章目录 相关链接前言Avalonia 官方文档Avalonia 环境配置我的本地环境下载Visual Studio Avalonia 插件 Avalonia 新建项目平台选择新建项目平台选择设计器选择扩展选择最终选择 默认项目运行 Avalonia 官方Demo总结 相关链接 Avalonia学习笔记 CSDN博客专栏 前言 最近想了解…

揭秘智能商品计划管理系统:为何服装企业老板争相引入?

在如今日新月异的商业环境中&#xff0c;服装企业老板们纷纷将目光转向了一种名为“智能商品计划管理系统”的创新工具。这种系统不仅具有高度的自动化和智能化特性&#xff0c;还能显著提升企业的运营效率、减少库存积压&#xff0c;并帮助企业在激烈的市场竞争中占据优势地位…

springboot当中使用EMQX(MQTT协议)

本篇博客主要围绕EMQX是什么&#xff1f;、能干什么&#xff1f;、怎么用&#xff1f; 三点来进行整理。 1、MQTT协议 1.1、MQTT简介 在了解EMQX前首先了解一下MQTT协议&#xff0c;MQTT 全称为 Message Queuing Telemetry Transport&#xff08;消息队列遥测传输&#xff0…

【从Python基础到深度学习】 8. VIM两种状态

一、安装 sudo apt install vim 二、VIM两种模式 - 命令状态/编辑状态 1.1 进入/退出VIM 进入VIM vim 退出vim :q <enter> 2.2 根目录下添加配置文件 window下创建vimrc类型文件内容如下&#xff1a; set nu set cursorline set hlsearch set tabstop4 使用Wins…

如何在CentOS安装SQL Server数据库并实现无公网ip环境远程连接

文章目录 前言1. 安装sql server2. 局域网测试连接3. 安装cpolar内网穿透4. 将sqlserver映射到公网5. 公网远程连接6.固定连接公网地址7.使用固定公网地址连接 前言 简单几步实现在Linux centos环境下安装部署sql server数据库&#xff0c;并结合cpolar内网穿透工具&#xff0…

http相关概念以及apache的功能

概念 互联网&#xff1a;是网络的网络&#xff0c;是所有类型网络的母集 因特网&#xff1a;世界上最大的互联网网络 万维网&#xff1a;www &#xff08;不是网络&#xff0c;而是数据库&#xff09;是网页与网页之间的跳转关系 URL:万维网使用统一资源定位符&#xff0c;…

【JVM篇】ThreadLocal中为什么要使用弱引用

文章目录 &#x1f354;ThreadLocal中为什么要使用弱引用⭐总结 &#x1f354;ThreadLocal中为什么要使用弱引用 ThreadLocal可以在线程中存放线程的本地变量&#xff0c;保证数据的线程安全 ThreadLocal是这样子保存对象的&#xff1a; 在每个线程中&#xff0c;存放了一个…

前端新手Vue3+Vite+Ts+Pinia+Sass项目指北系列文章 —— 第十一章 基础界面开发 (组件封装和使用)

前言 Vue 是前端开发中非常常见的一种框架&#xff0c;它的易用性和灵活性使得它成为了很多开发者的首选。而在 Vue2 版本中&#xff0c;组件的开发也变得非常简单&#xff0c;但随着 Vue3 版本的发布&#xff0c;组件开发有了更多的特性和优化&#xff0c;为我们的业务开发带…

有事休假店铺无人看守怎么办?智能远程视频监控系统保卫店铺安全

在春节期间&#xff0c;很多自营店主也得到了久违的假期&#xff0c;虽然很多店主都是长期在店铺中看守&#xff0c;但遇到春节这样的日子&#xff0c;多数人还是选择回乡休假。面对店主休假或有事不能管理店铺时&#xff0c;传统的监控虽然可以做到单一的监控&#xff0c;却仍…

用HTML Canvas和JavaScript创建美丽的花朵动画效果

目录 一、程序代码 二、代码原理 三、运行效果 一、程序代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>炫酷花朵</title><style>* {margin: 0;padding: 0;overflow: hidden;bac…

Windows 使设置更改立即生效——并行发送广播消息

目录 前言 1 遍历窗口句柄列表 2 使用 SendMessageTimeout 发送延时消息 3 并行发送消息实现模拟广播消息 4 修改 UIPI 消息过滤器设置 5 托盘图标刷新的处理 6 完整代码和测试 本文属于原创文章&#xff0c;转载请注明出处&#xff1a; https://blog.csdn.net/qq_5907…

不知如何获取1688工厂档案信息,你还在为此烦恼吗?

阿里巴巴集团旗下的B2B电子商务网站&#xff0c;提供海量优质商品&#xff0c;为采购商和供应商提供交流、合作、采购等服务&#xff0c;是很多没有货源优势的电商卖家首选的货源途径&#xff0c;也是国内最大、货源种类最齐全的货源网站。 不少做跨境电商无货源的朋友都想要1…

c# #if 与 Conditional属性宏的区别

测试代码 using System; using System.Diagnostics;namespace ConsoleApp1 {public class TestClass{[Conditional("Debug1")]public static void Func1(){Console.WriteLine("Conditional 宏");}public static void Func2(){ #if Debug2Console.WriteLin…

欠定方程组及其求解

欠定方程组是指方程的数量少于未知数的数量的方程组。在这种情况下&#xff0c;通常有无限多个解&#xff0c;因为给定的方程不足以唯一确定所有未知数的值。在某些情况下&#xff0c;我们可以利用额外的信息或假设&#xff0c;如稀疏性或其他约束&#xff0c;来找到一个合理的…

AT24C02(I2C总线)通信的学习

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、存储器介绍二、AT24C02芯片二、I2C总线I2C电路规范I2C时序结构I2C数据帧AT24C02数据帧 总结 前言 学习AT24C02(I2C总线)芯片 一、存储器介绍 RAM&#xf…

更改WordPress作者存档链接author和Slug插件Edit Author Slug

WordPress默认所有用户的存档永久链接都是/author/username/&#xff0c;不管是管理员还是订阅者或贡献者或作者或编辑。如果你想要自定义用户存档链接&#xff0c;比如根据角色不同使用不一样的author&#xff0c;或者自定义作者链接中的用户名Slug&#xff0c;那么建议考虑使…