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

Java——二叉树的最近公共祖先及二叉搜索树介绍

目录

二叉树的最近公共祖先

题目 

思路一:如果给定的是一颗二叉搜索树,

思路二:假设是孩子双亲表示法

 二叉搜索树

定义Node类

查找

删除

插入


二叉树的最近公共祖先

题目 

给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。

百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

提示:

树中节点数目在范围 [2, 105] 内。
-109 <= Node.val <= 109
所有 Node.val 互不相同 。
p != q
p 和 q 均存在于给定的二叉树中

思路一:如果给定的是一颗二叉搜索树,

二叉搜索树:中序遍历的大小是有序的,根节点的左树都比根节点的小,根节点的右树都比根节点大。

 

class Solution {public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {//先根据二叉搜索树来写if(root==null) return null;if(root==p||root==q) return root;TreeNode leftT=lowestCommonAncestor(root.left,p,q);TreeNode rightT=lowestCommonAncestor(root.right,p,q);if(leftT!=null&&rightT!=null){return root;}else if(leftT!=null){return leftT;}else{return rightT;}}
}

思路二:假设是孩子双亲表示法

就相当于链表求交点,但是我们的表示中没有双亲结点,因此我们引入两个栈。

1.用两个栈 存储root->q,root->p的路径;

2.求栈的大小;

3.让栈中多的元素出差值个元素;

4.开始出栈,直到栈顶元素相同,就是公共祖先;

如何去找到从根节点到一个指定节点的路径? 

class Solution {//root根结点,node:指定的节点,stack:存放根节点到指定节点的路径public boolean getPath(TreeNode root,TreeNode node ,Stack<TreeNode> stack){if(root==null||node==null) return false;stack.push(root);if(node==root) return true;boolean flg=getPath(root.left,node,stack);if(flg==true) return true;//找到啦flg=getPath(root.right,node,stack);if(flg==true) return true;//找到啦stack.pop();return false;}public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {if(root==null) return null;Stack<TreeNode> stack1=new Stack<>();getPath(root,p,stack1);Stack<TreeNode> stack2=new Stack<>();getPath(root,q,stack2);int size1=stack1.size();int size2=stack2.size();if(size1>size2){int size=size1-size2;while(size!=0){stack1.pop();size--;}while(!stack1.isEmpty()&&!stack2.isEmpty()){//直接判断地址if(stack1.peek()==stack2.peek()){return stack1.pop();}else{stack1.pop();stack2.pop();}}}else{int size=size2-size1;while(size!=0){stack2.pop();size--;}while(!stack1.isEmpty()&&!stack2.isEmpty()){//直接判断地址if(stack1.peek()==stack2.peek()){return stack2.pop();}else{stack1.pop();stack2.pop();}}}return null;}
}

 二叉搜索树

是空树或者:
若它的左子树不为空,则左子树上所有节点的值都小于根节点的值
若它的右子树不为空,则右子树上所有节点的值都大于根节点的值
它的左右子树也分别为二叉搜索树

定义Node类

class Node{public int val;public Node left;public Node right;public Node(int val){this.val=val;}
}

查找

  public Node root=null;public Node search(int key){Node cur = root;if(cur.val<key){cur = cur.right;}else if(cur.val>key){cur = cur.left;}else{return cur;}return null;}

删除

设待删除结点为 cur, 待删除结点的双亲结点为 parent
1. cur.left == null
1. cur root,则 root = cur.right
2. cur 不是 rootcur parent.left,则 parent.left = cur.right
3. cur 不是 rootcur parent.right,则 parent.right = cur.right
2. cur.right == null
1. cur root,则 root = cur.left
2. cur 不是 rootcur parent.left,则 parent.left = cur.left
3. cur 不是 rootcur parent.right,则 parent.right = cur.left
3. cur.left != null && cur.right != null
1. 需要使用替换法进行删除,即在它的右子树中寻找中序下的第一个结点(关键码最小),用它的值填补到被
删除节点中,再来处理该结点的删除问题

   //要删除节点,你需要知道这个节点的父节点//当要删除的节点的左节点为空//一般删除节点都是删除叶子节点public void f(Node cur,Node parent){if(cur.left==null){//当删除的节点左边没有节点if(cur==root){root=cur.right;}else if(cur==parent.left){parent.left=cur.right;}else{parent.right=cur.right;}}else if(cur.right==null){if(cur==root){root=cur.left;}else if(cur==parent.left){parent.left=cur.left;}else{parent.right=cur.left;}}else{//左右节点都不是空//相当于在右树中找一个较小值换到那个位置//或者就是在左树中找较大值//Node targetParent=cur;Node target=cur.right;while(target.left!=null){targetParent=target;target=target.left;}cur.val=target.val;if(target==targetParent.left){targetParent.left=target.right;}else{targetParent.right=target.right;}}}public void remove(int key){Node cur=root;Node parent=null;while(cur!=null){if(cur.val==key){f(cur,parent);break;}else if(cur.val<key){parent=cur;cur=cur.right;}else{parent=cur;cur=cur.left;}}}

插入

   //二叉搜索树插入的数据一定是在叶子节点//1.cur,parent来找到val需要存储的位置//2.parent.val比较大小,确定格式在左边还是右边进行插入public  boolean insert(int val){if(root == null){root = new Node(val);return true;}Node cur = root;Node parent = null;//找到parent的位置while(cur!=null){if(cur.val<val){parent=cur;cur=cur.right;}else if(cur.val==val){//bureturn false;}else{parent=cur;cur=cur.left;}}//找到对应位置开始插入Node node=new Node(val);if(parent.val<val){parent.right=node;}else{parent.left=node;}return true;}

相关文章:

Java——二叉树的最近公共祖先及二叉搜索树介绍

目录 二叉树的最近公共祖先 题目 思路一&#xff1a;如果给定的是一颗二叉搜索树&#xff0c; 思路二&#xff1a;假设是孩子双亲表示法 二叉搜索树 定义Node类 查找 删除 插入 二叉树的最近公共祖先 题目 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 百度百…...

Stable Diffusion加chilloutmixni真人图片生成模型,AI绘图杀疯了

上期图文教程,我们分享过AI绘图大模型Stable Diffusion以及中文版本文心AI绘画大模型的基础知识以及代码实现,截至到目前为止。Stable Diffusion模型已经更新到了V2.1版本,其文生图大模型也越来越火,其在2022年底,由AI绘制的图片被荣为国际大奖,让大家对AI绘画大模型也越…...

Matplotlib 绘图实用大全

本文只介绍最简单基本的画图方法 预设 要想画出来的图有些逼格&#xff0c;首先应该进行如下设置 plt.rcParams[font.sans-serif][SimHei] #画图时显示中文字体 plt.rcParams[axes.unicode_minus] False #防止因修改成中文字符&#xff0c;导致某些 unicode 字符不能…...

MyBatis源码用了哪些设计模式?

MyBatis源码用了哪些设计模式&#xff1f;前言一、创建型模式工厂模式单例模式建造者模式二、结构型模式适配器模式代理模式组合模式装饰器模式三、行为型模式模板模式策略模式迭代器模式总结前言 在 MyBatis 的两万多行的框架源码中&#xff0c;使用了大量的设计模式对工程架…...

【16.整数转罗马数字】

罗马数字包含以下七种字符&#xff1a; I&#xff0c; V&#xff0c; X&#xff0c; L&#xff0c;C&#xff0c;D 和 M。 字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 M 1000 例…...

前端小技巧

1.html 1.1 网站自动刷新 应用场景&#xff1a; 网页定期自动刷新&#xff08;现在基本淘汰了&#xff0c;采用ajax&#xff09;&#xff1b;自动跳转到指定页面&#xff0c;这个自动跳转的好处就是不需要JS调用&#xff0c;属于纯html网页自动跳转 v7-网站自动刷新 你可以…...

Servlet2.0

文章目录更方便的部署方式安装插件使用插件验证程序常见访问出错的解决方案404错误405错误500错误空白页面无法访问此网站在文章 TomcatServlet初识中&#xff0c;我们通过七个大的步骤才可以完成一个简单的Servlet程序&#xff0c;这个过程无疑是非常繁琐的&#xff0c;那么我…...

【c++】继承

目录 一、继承的表现 子类对父类成员的访问权限 二、父类与子类之间的相互赋值 三、继承的作用域 如果是父类和子类构成隐藏呢&#xff1f; 四、子类的成员函数怎么写 1.default构造函数 2.析构函数 所以析构函数不需要我们显式调用。 五、继承与友元函数 六、继承与静…...

minio安装配置和使用(二)客户端安装

安装minio客户端mcli 命令如下&#xff1a; dnf install https://dl.minio.org.cn/client/mc/release/linux-amd64/mcli-20230128202938.0.0.x86_64.rpm 安装完成&#xff0c;在/usr/local/bin/下新增了mcli命令 mcli是对minio进行管理的命令。功能丰富&#xff0c; 基本格式…...

【如何使用Arduino设置GRBL和控制CNC机床】

【如何使用Arduino设置GRBL和控制CNC机床】 前言1. 什么是GRBL?2. 所需硬件3. 如何安装GRBL4. GRBL 配置5. GRBL 控制器5.1 如何使用通用 G 代码发送器5.2 波特率5.3 电机方向5.4 步进比例系数5.5 限位开关5.6 数控机床的归位设置6. 结论前言 如果您正在考虑或正在制造自己的…...

项目测试——博客系统

文章目录项目测试——博客系统项目简介项目功能测试计划web自动化测试1. 测试用例2.web自动化测试说明项目测试——博客系统 项目简介 博客系统主要分为8大模块&#xff0c;分别是注册页&#xff0c;登录页&#xff0c;编辑页&#xff0c;修改页&#xff0c;个人主页&#xf…...

【C习题】经典数组与指针面试题(万字)

文章目录一. 一维数组二.字符数组三.字符指针四.二维数组五.指针笔试题一. 一维数组 首先说明&#xff1a;需熟记以下三个规则。 规则1.&数组名指的是取出整个数组的地址。 规则2.数组名被单独放在sizeof内部&#xff0c;计算的是整个数组的大小。 说明&#xff1a;这里的单…...

【ArcGIS Pro二次开发】(13):ProWindow的用法

ProWindow是ArcGIS Pro SDK中的一个WPF控件&#xff0c;具有以下特点&#xff1a; 可扩展性&#xff1a;ProWindow提供了丰富的API和样式&#xff0c;可以轻松地扩展和自定义ArcGIS Pro应用程序的UI。 可定制性&#xff1a;ProWindow支持多种UI控件和布局方式&#xff0c;可以…...

HTML/CSS/JS 基本语法

前端一、HTNL1、文件结构2、文本标签&#xff08;1&#xff09;块元素&#xff1a;div&#xff08;2&#xff09;行内元素&#xff1a;span&#xff08;3&#xff09;格式标签3、图片、音频、视频&#xff08;1&#xff09;图片&#xff08;2&#xff09;音频< audio >&a…...

对于从事芯片行业的人来说,有哪些知识是需要储备的?

近两年芯片行业大火&#xff0c;不少同学想要转行&#xff0c;却不知道该如何下手&#xff0c;需要学习哪些基础知识&#xff0c;下面就来看看资深工程师怎么说&#xff1f; 随着工艺的发展&#xff0c;芯片肯定是尺寸越来越小&#xff0c;至于小到什么样的程度是极限&#xf…...

测试场景设计

测试场景设计 又叫做场景法。其实对于场景法是测试用例中面临最多的&#xff0c;但是这种模式不是很容易总结&#xff0c;有时候是基于经验&#xff0c;有时候是我们对系统的了解。所以在这种情况下&#xff0c;我们强硬的用场景法对其进行规范。 场景法原理 现在的软件几乎…...

《重构》增强代码可读性

文章目录重构原则何为重构为何重构何时重构重构会影响性能吗实例原始类进行重构分解statements方法提取函数搬移函数提炼“积分计算”功能去除临时变量&#xff08;以查询取代临时变量&#xff09;运用多态取代与价格相关的条件逻辑代码迁移Movie类Price类 状态模式搬移函数以多…...

数据分析自学路线

数据分析作为近几年火起来的IT技术岗位&#xff0c;在大数据时代的浪潮下迅速发酵膨胀&#xff0c;席卷了众多互联网企业&#xff0c;漫延到了金融、教育、医疗、消费等传统行业&#xff0c;在新经济领域也有重要作用&#xff0c;比如人工智能、新能源、电子芯片、企业数字化服…...

蓝桥杯C++组怒刷50道真题

&#x1f33c;深夜伤感网抑云 - 南辰Music/御小兮 - 单曲 - 网易云音乐 &#x1f33c;多年后再见你 - 乔洋/周林枫 - 单曲 - 网易云音乐 50题才停更&#xff0c;课业繁忙&#xff0c;有时间就更&#xff0c;2023/3/14/15:06写下 目录 &#x1f44a;填空题 &#x1f33c;一…...

【期末小作业】HTML、CSS前端静态网页

分享一个可以“趁别人喝咖啡的功夫“”写的一个静态网页&#xff0c;纯纯练手小项目&#xff0c;适合前端刚入门的小白练练手。 前端练手静态页面 实现效果图展示 CSS代码 HTML 代码 环境&#xff1a;VScode编辑器 语言&#xff1a;HTML 、CSS 一、实现效果图 仅仅通过…...

web vue 项目 Docker化部署

Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段&#xff1a; 构建阶段&#xff08;Build Stage&#xff09;&#xff1a…...

Vue记事本应用实现教程

文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展&#xff1a;显示创建时间8. 功能扩展&#xff1a;记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】

微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来&#xff0c;Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...

家政维修平台实战20:权限设计

目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系&#xff0c;主要是分成几个表&#xff0c;用户表我们是记录用户的基础信息&#xff0c;包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题&#xff0c;不同的角色&#xf…...

macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用

文章目录 问题现象问题原因解决办法 问题现象 macOS启动台&#xff08;Launchpad&#xff09;多出来了&#xff1a;Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显&#xff0c;都是Google家的办公全家桶。这些应用并不是通过独立安装的…...

视频字幕质量评估的大规模细粒度基准

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用&#xff0c;因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型&#xff08;VLMs&#xff09;在字幕生成方面…...

GitHub 趋势日报 (2025年06月08日)

&#x1f4ca; 由 TrendForge 系统生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...

React---day11

14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store&#xff1a; 我们在使用异步的时候理应是要使用中间件的&#xff0c;但是configureStore 已经自动集成了 redux-thunk&#xff0c;注意action里面要返回函数 import { configureS…...

HashMap中的put方法执行流程(流程图)

1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中&#xff0c;其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下&#xff1a; 初始判断与哈希计算&#xff1a; 首先&#xff0c;putVal 方法会检查当前的 table&#xff08;也就…...

视频行为标注工具BehaviLabel(源码+使用介绍+Windows.Exe版本)

前言&#xff1a; 最近在做行为检测相关的模型&#xff0c;用的是时空图卷积网络&#xff08;STGCN&#xff09;&#xff0c;但原有kinetic-400数据集数据质量较低&#xff0c;需要进行细粒度的标注&#xff0c;同时粗略搜了下已有开源工具基本都集中于图像分割这块&#xff0c…...