二叉树的最近公共祖先LCA

news2025/1/20 5:53:23

一、什么是最近公共祖先

LCA为最近公共祖先(Lowest Common Ancestor)的缩写。
对于一棵有根树T的两个节点u,v,最近公共祖先LCA(T,u,v)代表一个节点x。
在这里插入图片描述
LCA(5,6) = 2
LCA(7,12) = 3
LCA(2,1)=1

二、公共祖先的朴素解法

  1. 两个节点先调整到相同的深度
  2. 每一次两个点同时向上跳一层,当两个点相遇即为所求两点的LCA.
    对于一组询问,时间复杂度为O(N)

在这里插入图片描述
需要深度遍历,然后构造出这么一张表

在这里插入图片描述
假设求LCA(D,G)
第一步:先判断D的深度为3,G的深度为1
第二步:将D根据父节点数组,往上走一步,也就是节点B,
第三步:此时深度B为2和1还是不同,需要继续往上,也就是A,此时 A,G的深度一致
第四步:判读A的父节点和G的父节点是否一致,如果一致则找到,不一致则同时上调一步,如此循环直到两者父节点首次相同。

三、递归解法

有以下图

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

四、代码

以下代码,构建了如下的一颗树,并分别实现了朴素法和递归法

在这里插入图片描述

#include<iostream>
using namespace std;
using ElemType = char;

typedef struct BiTNode
{
	ElemType data;
	int nIndex;
	struct BiTNode* lchild;
	struct BiTNode* rchild;

}BiTNode, * BiTree;

int arrayD[100] = { -1 };
int arrayF[100] = { -1 };
void DFS(BiTNode* tree, int nd, int nf)
{
	if (tree)
	{
		DFS(tree->lchild, nd + 1, tree->nIndex);
		arrayD[tree->nIndex] = nd;
		arrayF[tree->nIndex] = nf;
		DFS(tree->rchild, nd + 1, tree->nIndex);
	}
}

int LCA1(int u, int v)
{
	if (arrayD[u] < arrayD[v])
	{
		swap(u, v);
	}

	if (arrayD[u] > arrayD[v] && arrayF[u] != v)
	{
		while (arrayD[u] != arrayD[v])
		{
			u = arrayF[u];
		}

		while (arrayF[u] != arrayF[v])
		{
			u = arrayF[u];
			v = arrayF[v];
		}

	}

	return arrayF[u];

}

BiTNode* LCA2(BiTNode *pRoot,BiTNode *p,BiTNode *q)
{
	if (pRoot == p|| pRoot == q || pRoot == NULL)
	{
		return pRoot;
	}

	BiTNode* pLeft = LCA2(pRoot->lchild, p, q);
	BiTNode* pRight = LCA2(pRoot->rchild, p, q);

	if (pLeft && pRight)
	{
		return pRoot;
	}
	else if (pLeft)
	{
		return pLeft;
	}
	else if (pRight)
	{
		return pRight;
	}
	else
	{
		return NULL;
	}
}

int main()
{

	BiTNode b1, b2, b3, b4, b5, b6, b7;
	memset(&b1, 0, sizeof(BiTNode));
	memset(&b2, 0, sizeof(BiTNode));
	memset(&b3, 0, sizeof(BiTNode));
	memset(&b4, 0, sizeof(BiTNode));
	memset(&b5, 0, sizeof(BiTNode));
	memset(&b6, 0, sizeof(BiTNode));
	memset(&b7, 0, sizeof(BiTNode));

	b1.nIndex = 0; b1.data = 'A';
	b2.nIndex = 1; b2.data = 'B';
	b3.nIndex = 2; b3.data = 'C';
	b4.nIndex = 3; b4.data = 'D';
	b5.nIndex = 4; b5.data = 'E';
	b6.nIndex = 5; b6.data = 'F';
	b7.nIndex = 6; b7.data = 'G';
	//构建树关系
	b1.lchild = &b2;
	b1.rchild = &b3;
	b2.lchild = &b4;
	b2.rchild = &b5;

//根
b6.lchild = &b1;
b6.rchild = &b7;


cout << "LCA1:\n";
	DFS(&b6, 0, -1);

	int nIndex = LCA1(b1.nIndex, b2.nIndex);
	if (nIndex >= 0)
	{
		printf("LCA(%c,%c)= index(%d)\n", b1.data, b2.data, nIndex);
	}

	nIndex = LCA1(b5.nIndex, b7.nIndex);
	if (nIndex >= 0)
	{
		printf("LCA(%c,%c)= index(%d)\n", b5.data, b7.data, nIndex);
	}
	
	//LCA2
	cout << "LCA2:\n";

	BiTNode *pLCA = LCA2(&b6, &b1, &b2);
	if (pLCA)
	{
		printf("LCA(%c,%c)= %c\n",b1.data,b2.data, pLCA->data);
	}

	pLCA = LCA2(&b6, &b5, &b7);
	if (pLCA)
	{
		printf("LCA(%c,%c)= %c\n", b5.data, b7.data, pLCA->data);
	}
	system("pause");
}

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

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

相关文章

Qt6使用cmake创建项目

目录 创建普通项目 创建qt项目 创建具有资源文件的qt项目 在QT6中&#xff0c;官方推荐在新的项目中使用CMake。 在Qt Creator中使用CMake构建系统时&#xff0c;与往常的qmake有一些不一样&#xff0c;因此写一篇文章来记录一下。 创建普通项目 我们先写一个最简单的项目…

chatgpt赋能python:Python的Unicode编码介绍

Python的Unicode编码介绍 什么是Unicode Unicode是一个字符集&#xff0c;它定义了世界上几乎所有的字符&#xff0c;包括字母、数字、符号和标点。Unicode使用唯一的数字编码来表示每个字符&#xff0c;这使得在不同的操作系统和编程语言中展示和处理字符非常方便。在Python…

chatgpt赋能python:Python怎样完成更新?

Python怎样完成更新&#xff1f; Python是一种非常流行的编程语言&#xff0c;由于它的简单易学和广泛的应用领域&#xff0c;许多程序员选择使用Python编写程序。但是&#xff0c;随着时间的推移和技术的不停发展&#xff0c;Python需要不断更新以保持全球开发者的使用体验。…

ES 如何重建索引

场景&#xff1a; ES索引中&#xff0c;为了效率和存储空间&#xff0c;有些字段可以设定为不被索引&#xff0c;然后某一天又需要改成能索引&#xff0c;此时就需要对ES进行重建索引&#xff0c;操作如下 1、修改 ES 索引模板文件 cd /data/elk/logstash/es-template/ vim e…

JavaSE笔记(七)

Java反射和注解 **注意&#xff1a;**本章节涉及到JVM相关底层原理&#xff0c;难度会有一些大。 反射就是把Java类中的各个成分映射成一个个的Java对象。即在运行状态中&#xff0c;对于任意一个类&#xff0c;都能够知道这个类所有的属性和方法&#xff0c;对于任意一个对象…

几十款游戏的简单分析

文章目录 一、 介绍二、 影响游戏体验的因素三、 游戏能爆火的因素1.影响游戏爆火因素的排名2.玩游戏的两种经典心理3.经典案例分析Qq农场植物大战僵尸水果忍者召唤神龙羊了个羊 4.游戏公司可借鉴的经验5.未来游戏面对的诸多挑战 四、 几十款游戏的多方面分析FC红白游戏机十二人…

chatgpt赋能python:Python中的import使用详解

Python中的import使用详解 介绍 在Python中&#xff0c;import是将一个模块引入到当前脚本中使用的关键字。Python中的模块是指一个包含所有定义、函数和变量等的Python文件&#xff0c;也可以包含其他模块&#xff0c;从而构成一个Python程序。在Python中&#xff0c;有很多…

spark相关理论

系列文章目录 ubuntu虚拟机下搭建zookeeper集群&#xff0c;安装jdk压缩包&#xff0c;搭建Hadoop集群与spark集群的搭建【上篇】_ubuntu搭建zookeeper集群 ubuntu虚拟机下搭建zookeeper集群&#xff0c;安装jdk压缩包&#xff0c;搭建Hadoop集群与spark集群的搭建【下篇】 …

Redux基本使用和实践

Redux的核心是store&#xff0c;store作为应用状态的容器&#xff0c;保存着这个页面的状态数据树。 store 但是store本质上是一个JavaScript对象&#xff0c;这个对象含有了dispatch以及获取页面状态数据的方法等等。 如上图所示&#xff0c;store提供几个方法给开发者调用&…

[论文阅读笔记75]P-Tuning v2

1. 基本信息 题目论文作者与单位来源年份P-Tuning v2: Prompt Tuning Can Be Comparable to Fine-tuning Universally Across Scales and TasksXiao Liu等Tsinghua University清华大学2021 Citations, References 论文链接&#xff1a;https://arxiv.org/pdf/2110.07602.pdf…

chatgpt赋能python:Python的IDLE是什么?——初探IDLE的用途和功能

Python的IDLE是什么&#xff1f;——初探IDLE的用途和功能 Python的IDLE是一个Python集成开发环境(IDE)&#xff0c;可以简单地将其视为为开发者提供编写、调试和执行代码的工具。IDLE包括一个交互式解释器&#xff0c;使开发更加快速和简便。它还提供了代码编辑器、调试器和其…

chatgpt赋能python:Python技巧:一行代码实现所有数据的输出

Python技巧&#xff1a;一行代码实现所有数据的输出 Python是一种高级动态语言&#xff0c;因其简单易学和灵活性而广受欢迎。Python的语法简单明了&#xff0c;适合初学者学习、理解和实践&#xff0c;同时也是专业程序员的首选开发语言之一。 在实际的编程中&#xff0c;有…

k8s简单部署示例

1 部署yaml文件 1.1 Deployment部署 apiVersion: apps/v1 kind: Deployment metadata:name: zscorenamespace: wangzy-plabels:app: zscore-dep spec:replicas: 1selector:matchLabels:app: zscoretemplate:metadata:labels:app: zscoreannotations:sidecar.istio.io/inject:…

[工业互联-9]:EtherCAT(以太网控制自动化技术)+TwinCAT 在生产自动化控制中的应用 、

前言 EtherCAT&#xff08;以太网控制自动化技术&#xff09;是一个开放架构&#xff0c;以以太网为基础的现场总线系统&#xff0c;其名称的CAT为控制自动化技术&#xff08;Control Automation Technology&#xff09;字首的缩写。EtherCAT是确定性的工业以太网&#xff0c;…

Android 源码 AOSP版本– 下载[Ubuntu ]

Android 源码 AOSP版本– 下载[Ubuntu ] 前言配置下载源码前言 Android系统作为一个庞大的开源项目,除了一些谷歌自带服务之外,其他所有代码均以AOSP(Android Open Source Project)的形式开源。对于框架开发者来说,熟悉AOSP是必不可少的知识。即使是普通开发者,为了优化…

POSTGRES 多条件数量统计---CASE WHEN 妙用

创建表 create table tbl_user( id serial PRIMARY KEY, name varchar(256), addr varchar(256), age int, score int, fav varchar(256) ) 插入预置数据 INSERT INTO tbl_user (name, addr, age, score, fav) VALUES (aaa,aaa_addr,10, 23,aaa_fav_new), (bbb,ccc_addr,10, 23…

chatgpt赋能python:Python之妙用一行输出一个数字

Python之妙用一行输出一个数字 在日常编程中&#xff0c;我们常常需要输出一些数字来进行调试或测试。而在Python中&#xff0c;一行代码就可以轻松实现这个过程&#xff0c;即一行代码输出一个数字。 Python的print()函数 在Python中&#xff0c;print()函数是最基本的输出…

CPU lock-step资料整理

知识的价值在于分享&#xff0c;欢迎大家批评指正&#xff0c;共同进步。 目录 1 功能安全 2 技术特性 3 安全系统架构 4 TI Hercules系列 4.1 TMS570安全概念基本原理 4.1.1 1oo1D双核安全概念 4.1.2 1oo1D优势 总结 参考文献 1 功能安全 根据ISO26262-2018&#xff0…

踩坑集锦之Mybaits Invalid bound statement异常

踩坑集锦之Mybaits Invalid bound statement 引言多数据源场景下Mybaits如何进行配置包扫描过程问题一: 自动注入带来的同类型bean实例冲突问题二: 扫描器扫描路径重叠&#xff0c;导致优先级低的扫描器扫描不到对应包路径下的mapper接口补充说明1: MapperScannerConfigurer补充…

编译tolua——1、编译工具和环境说明

大家好&#xff0c;我是阿赵。 之前有朋友问我编译tolua相关的问题。虽然网上也有很多相关的资料可以查询&#xff0c;但我感觉自己也写一篇&#xff0c;作为一个记录也不错。不过一篇文章要把所有内容都说完&#xff0c;可能有点长&#xff0c;所以把整个过程分开几篇文章写一…