二叉树的最近公共祖先【Java实现】

news2024/10/6 1:44:44

题目描述

现有一棵n个结点的二叉树(结点编号为从0n-1,根结点为0号结点),求两个指定编号结点的最近公共祖先。

注:二叉树上两个结点A、B的最近公共祖先是指:二叉树上存在的一个结点P,使得P既是A的祖先,又是B的祖先,并且P需要离根结点尽可能远(即层号尽可能大)。

输入描述

第一行3个整数n、k1、k2(1≤n≤50,0≤k1≤n−1,0≤k2≤n−1),分别表示二叉树的结点个数、需要求最近公共祖先的两个结点的编号;

接下来n行,每行一个结点,按顺序给出编号从0n-1的结点的左子结点编号和右子结点编号,中间用空格隔开。如果不存在对应的子结点,那么用-1表示。

输出描述

输出一个整数,表示最近公共祖先的编号。

样例

输入

6 1 4			// 共有6个节点【编号0~5】,目标节点编号为1和4
2 5			// 0号节点的左节点为2号节点,右节点为5号节点
-1 -1		// 1号节点左右节点都为空
1 4			// 2号节点左节点为1号节点,右节点为4号节点
-1 -1		// ...依次类推
-1 -1
-1 3
image-20230305170515544

输出

2	// 1号节点和4号节点在上述树结构中的祖先节点为2号节点

思路分析

  • 所谓祖先节点一定是我们的目标节点或在它的上层,也就是我们得把当前节点的下面部分遍历完,才能判断当前节点是不是祖先节点。

    在树的三种遍历中,先把下面遍历完在判断当前节点的遍历方式显而易见,是后序遍历,确定遍历方式是解决问题的第一步。

  • 第二步是设立边界,即怎样判断当前节点是不是祖先节点,或者怎样确定它一定不是祖先节点

    1. 如果当前节点左子树部分存在目标节点,右子树部分也存在目标节点,那么可以确定当前节点一定是祖先节点
    2. 如果当前节点是目标节点,且左右子树中也存在一个目标节点,则可以确定当前节点一定是祖先节点
    3. 除上述两种情况外,其余情况皆为非祖先节点
  • 明确步骤之后,我们设计的函数应当返回当前节点左右子树或自身是否包含目标节点,若包含返回true,不包含返回false,并且在后序遍历过程中记录下满足条件的祖先节点。

代码实现

package homework;

import java.util.Scanner;


public class Main {
	static int ans = -1;

	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		int n = scanner.nextInt();
		TreeNode arrs[] = new TreeNode[n];
		int k1 = scanner.nextInt();
		int k2 = scanner.nextInt();
		for (int i = 0; i < n; i++) {
			TreeNode node = new TreeNode();
			node.left = scanner.nextInt();
			node.right = scanner.nextInt();
			arrs[i] = node;
		}
		findAncestorByPostOrder(arrs, 0, k1, k2);
		System.out.println(ans);

	}

	public static boolean findAncestorByPostOrder(TreeNode arrs[], int index, int k1, int k2) {
		if (index == -1) {
			return false;
		}
		boolean left = findAncestorByPostOrder(arrs, arrs[index].left, k1, k2);
		boolean right = findAncestorByPostOrder(arrs, arrs[index].right, k1, k2);
		// 说明当前节点是目标之一
		boolean flag = index == k1 || index == k2;
		// 当前节点为目标节点主要对应如下两种情况:
		// 1. 当左右同时为目标;
		// 2. 当左边或者右边有一个为目标,且当前也是目标之一
		if ((left && right) || ((left || right) && flag)) {
			ans = index;
		}
		// 如果当前节点左右存在目标节点,或者当前节点就是目标节点时返回 true
		return left || right || flag;
	}

}

class TreeNode {
	int left;
	int right;


}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

4万字数字政府建设总体规划方案WORD

本资料来源公开网络&#xff0c;仅供个人学习&#xff0c;请勿商用。部分资料内容&#xff1a; 我省“数字政府”架构 &#xff08;一&#xff09; 总体架构。 “数字政府”总体架构包括管理架构、业务架构、技术架构。其中&#xff0c;管理架构体现“管运分离”的建设运营模式…

面试必须要知道的常见排序算法

以下排序均为升序 1.直接插入排序 具体思想 把待排序的数据按大小比较插入到一个已经排序好的有序序列中,直到所有的待排序数据全部插入到有序序列中为止.实际生活中,我们平常斗地主摸牌时,就用到了插入排序的思想. 当插入第n个数据时,前面n-1个数据已经有序;第n个数据依次与前…

WebStorm安装教程【2023年最新版图解】一文教会你安装

文章目录引言一、下载WebStorm三、WebStorm激活配置及创建项目Active Code安装完成尝试新建一个项目引言 今天发现了一个专注前端开发的软件&#xff0c;相比VSCode的话&#xff0c;这个好像也不错&#xff0c;为了后续做个API接口项目做准备。 对于入门JavaScript 开发的者&am…

Linux操作系统学习(信号处理)

文章目录进程信号信号的产生方式&#xff08;信号产生前&#xff09;1. 硬件产生2.调用系统函数向进程发信号3.软件产生4.定位进程崩溃的代码&#xff08;进程异常退出产生信号&#xff09;信号保存的方式&#xff08;信号产生中&#xff09;获取pending表&&修改block表…

四轮两驱小车(五):蓝牙HC-08通信

前言&#xff1a; 在我没接触蓝牙之前&#xff0c;我觉得蓝牙模块应用起来应该挺麻烦&#xff0c;后来发觉这个蓝牙模块的应用本质无非就是一个串口 蓝牙模块&#xff1a; 这是我从某宝上买到的蓝牙模块HC-08&#xff0c;价格还算可以&#xff0c;而且可以适用于大多数蓝牙调试…

闲人闲谈PS之三十八——混合制生产下WBS-BOM价格发布增强

惯例闲话&#xff1a;最近中《三体》的毒很深&#xff0c;可能是电视剧版确实给闲人这种原著粉带来太多的感动&#xff0c;又一次引发了怀旧的热潮&#xff0c;《我的三体-罗辑传》是每天睡前必刷的视频&#xff0c;结尾BGM太燃了。闲人对其中一句台词感触很深——人类不感谢罗…

taobao.itemprops.get( 获取标准商品类目属性 )

&#xffe5;开放平台基础API不需用户授权 通过设置必要的参数&#xff0c;来获取商品后台标准类目属性&#xff0c;以及这些属性里面详细的属性值prop_values。 公共参数 请求地址: HTTP地址 http://gw.api.taobao.com/router/rest 公共请求参数: 公共响应参数: 请求参数 点…

数据结构:复杂度的练习(笔记)

数据结构&#xff1a;复杂度的练习&#xff08;笔记&#xff09; 例题一&#xff1a; 可以先给数组排序&#xff0c;然后再创建一个i值&#xff0c;让他循环一次一次&#xff0c;遍历这个排序后的数组&#xff0c;但如果用qsort函数进行排序&#xff0c;时间复杂度就和题目要求…

Vue组件进阶(动态组件,组件缓存,组件插槽,具名插槽,作用域插槽)与自定义指令

Vue组件进阶与自定义指令一、Vue组件进阶1.1 动态组件1.2 组件缓存1.3 组件激活和非激活1.4 组件插槽1.5 具名插槽1.6 作用域插槽1.7 作用域插槽使用场景二、自定义指令2.1 自定义指令--注册2.2 自定义指令-传参一、Vue组件进阶 1.1 动态组件 多个组件使用同一个挂载点&#x…

如何打造一款专属于自己的高逼格电脑桌面

作为一名电脑重度使用者&#xff0c;你是否拥有一款属于你自己的高逼格电脑桌面呢&#xff1f;你是不是也像大多数同学一样&#xff0c;会把所有的内容全部都堆积到电脑桌面&#xff0c;不仅找东西困难&#xff0c;由于桌面内容太多还会导致C盘空间不足&#xff0c;影响电脑的反…

Java分布式解决方案(一)

随着互联网的不断发展&#xff0c;互联网企业的业务在飞速变化&#xff0c;推动着系统架构也在不断地发生变化。 如今微服务技术越来越成熟&#xff0c;很多企业都采用微服务架构来支撑内部及对外的业务&#xff0c;尤其是在高 并发大流量的电商业务场景下&#xff0c;微服务…

Linux内核学习笔记——页表的那些事。

目录页表什么时候创建内核页表变化什么时候更新到用户页表源码分析常见问题解答问题一&#xff1a;页表到底是保存在内核空间中还是用户空间中&#xff1f;问题2&#xff1a;页表访问&#xff0c;软件是不是会频繁陷入内核&#xff1f;问题3&#xff1a;内存申请&#xff0c;软…

LaTeX表格自定义行高+自定义列宽+大表格自适应页面宽度

一、自定义行高 默认行高效果 自定义行高效果&#xff1a;看起来更美观、大方些 实现方式&#xff1a;在LaTeX表格中的\begin{table}和\begin{tabular}之间插入命令\renewcommand\arraystretch{1.5}&#xff0c;其中1.5这个数值是可以自定义的&#xff0c;数值越大&#xff0c;…

xmu 离散数学 卢杨班作业详解【8-12章】

文章目录第八章 树23456810第九章46811第十章24567第十一章14571116第十二章131317第八章 树 2 (2) 设有k片树叶 2∗m2∗43∗3k2*m2*43*3k2∗m2∗43∗3k n23kn23kn23k mn−1mn-1mn−1 联立解得k9 T中有9片树叶 3 有三颗非同构的生成树 4 (1) c --abc e–abed f–dgf…

2023.03.05 学习周报

文章目录摘要文献阅读1.题目2.摘要3.介绍4.SAMPLING THE OUTPUT5.LOSS FUNCTION DESIGN5.1 ranking loss: Top1 & BPR5.2 VANISHING GRADIENTS5.3 ranking-max loss fuction5.4 BPR-max with score regularization6.实验7.结论深度学习1.相关性1.1 什么是相关性1.2 协方差1…

套接字实现TCP

套接字 套接字的意义就是客户端与服务器进行双向通信的端点&#xff0c;如果有不理解点上面套接字三字更近距离了解套接字。 网络套接字与客户连接的特定网络有关的服务端口号&#xff0c;这个端口号允许linux进入特定的端口号的连接转到正确的服务器进程。 套接字通信的建立过…

【数据结构与算法】数据结构有哪些?算法有哪些?

1. 算法与数据结构总览图 2.常用的数据结构 2.1.数组&#xff08;Array&#xff09; 数组是一种聚合数据类型&#xff0c;它是将具有相同类型的若干变量有序地组织在一起的集合。数组可以说是最基本的数据结构&#xff0c;在各种编程语言中都有对应。一个数组可以分解为多个数…

k8s篇之Pod 干预与 PDB

文章目录自愿干预和非自愿干预PDBPDB 示例分离集群所有者和应用程序所有者角色如何在集群上执行中断操作自愿干预和非自愿干预 Pod 不会消失&#xff0c;除非有人&#xff08;用户或控制器&#xff09;将其销毁&#xff0c;或者出现了不可避免的硬件或软件系统错误。 我们把这…

Vue+ECharts实现可视化大屏

由于项目需要一个数据大屏页面&#xff0c;所以今天学习了vue结合echarts的图标绘制 首先需要安装ECharts npm install echarts --save因为只是在数据大屏页面绘制图表&#xff0c;所以我们无需把它设置为全局变量。 可以直接在该页面引入echarts&#xff0c;就可以在数据大…

『MyBatis技术内幕』源码调试前提

准备源代码包 下载源代码 3.4.6 版本 https://github.com/mybatis/mybatis-3/releases?page2 通过 idea 导入然后回自动下载所有依赖&#xff0c;根据 3.4.6 版本的 pom.xml 找到依赖的 mybatis-parent 版本 <parent><groupId>org.mybatis</groupId><ar…