Tree_Graph LCA(Lowest Common Ancestor) 最低公共节点 (BST或者一般树) @CareerCup

opencv去除印章痕迹 今天看到一个很有意思的程序,就是去除票据上的红色印章,觉得很有意思,就把它抄过来记录一下,同时自己也开了一下脑洞。 原来的程序来自:https://www.cnblogs.com/skyfsm/p/7638301.html 可以看到图像效果很不错,下面是源码实现: #include <iostream> #include <opencv2/imgproc/imgpro... 阅读详情

原文:

Design an algorithm and write code to find the first common ancestor of two nodes in a binary tree. Avoid storing additional nodes in a data structure. NOTE: This is not necessarily a binary search tree.

译文:

写程序在一棵二叉树中找到两个结点的第一个共同祖先。不允许存储额外的结点。注意: 这里不特指二叉查找树。


思路:

其实没有什么难得,入手点就是分情况,搞清楚p,q能在树的位置的各种情况。

我们可以从根结点开始,判断以当前结点为根的树中左右子树是不是包含我们要找的两个结点。如果两个结点都出现在它的左子树中,那最低的共同父结点也出现在它的左子树中。如果两个结点都出现在它的右子树中,那最低的共同父结点也出现在它的右子树中。如果两个结点一个出现在左子树中,一个出现在右子树中,那当前的结点就是最低的共同父结点


package Tree_Graph;

import CtCILibrary.TreeNode;

public class S4_7 {

	
	// ========================= 未优化递归版
	// 递归求公共祖先,Time:O(N)
	public static TreeNode commonAncestor(TreeNode root, TreeNode p, TreeNode q) {
		// 错误判断,如果有一个点根本不在树内,则报错!
		if(!isIn(root.left, p) || !isIn(root.right, q)) {
			return null;
		}
		return commonAncestorRec(root, p, q);
	}
	
	public static TreeNode commonAncestorRec(TreeNode root, TreeNode p, TreeNode q) {
		if(root == null) {
			return null;
		}
		if(root==p || root==q) {
			return root;
		}
		
		boolean isPInLeft = isIn(root.left, p);		// 判断p是否在树的左侧
		boolean isQInLeft = isIn(root.left, q);		// 判断q是否在树的左侧
		
		if(isPInLeft != isQInLeft){			// 如果一个在左侧一个在右侧,则公共祖先必然是root
			return root;
		}
		
		if(isPInLeft) {		// p,q都在左侧
			return commonAncestorRec(root.left, p, q);
		} else{				// p,q都在右侧
			return commonAncestorRec(root.right, p, q);
		}
	}
	
	// 判断节点p是否在root树中
	private static boolean isIn(TreeNode root, TreeNode node) {
		if(root == null) {
			return false;
		}
		if(root == node) {
			return true;
		}
		return isIn(root.left, node) || isIn(root.right, node);
	}
	
	
	
	// ========================= 优化递归版,待改动
	public static TreeNode commonAncestor2(TreeNode root, TreeNode p, TreeNode q) {
		Result res = commonAncestorRec2(root, p, q);
		if(res.isAncestor) {
			return res.node;
		}
		return null;
	}
	
	public static Result commonAncestorRec2(TreeNode root, TreeNode p, TreeNode q) {
		if(root == null) {
			return new Result(null, false);
		}
		if(root==p && root==q) {
			return new Result(root, true);
		}
		
		Result leftRes = commonAncestorRec2(root.left, p, q);
		if(leftRes.isAncestor) {		// 在左子树找到公共节点
			return leftRes;
		}
		
		Result rightRes = commonAncestorRec2(root.right, p, q);
		if(rightRes.isAncestor) {	// 在右子树找到公共节点
			return rightRes;
		}
		
		if(leftRes.node!=null && rightRes.node!=null) {
			return new Result(root, true);		// root为公共节点
		} 
		else if(root==p || root==q) {
			boolean isAncestor = (leftRes.node != null || rightRes.node != null) ? true : false;
			return new Result(root, isAncestor);
		} 
		else {
			return new Result(leftRes!=null ? leftRes.node : rightRes.node, false);
		}
	}
	
	static class Result {
		public TreeNode node;
		public boolean isAncestor;
		public Result(TreeNode n, boolean isAnc) {
			node = n;
			isAncestor = isAnc;
		}
	}
	
	
	public static void main(String[] args) {
		int[] array = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
		TreeNode root = TreeNode.createMinimalBST(array);
		TreeNode n3 = root.find(1);
		TreeNode n7 = root.find(7);
		TreeNode ancestor = commonAncestor(root, n3, n7);
		System.out.println(ancestor.data);
	}
}


Follow Up:

假如这棵树是BST,那么怎么做?

就不必用isIn函数了,直接把待判断节点的值与root相比较即可,下面写了递归和非递归版解法:


public class TreeNode {
    int data;
    TreeNode left, right;
}

// 递归 Time Complexity: O(h) h: 树高
// Space complexity: O(n) n:节点个数
public TreeNode lca(TreeNode root, TreeNode p, TreeNode q) {
    if(root == null) {
        return null;
    }
    if(p.data < root.data && q.data < root.data) {
        return lca(root.left, p, q);
    }
    if(p.data > root.data && q.data > root.data) {
        return lca(root.right, p, q);
    }
    return root;
}


// Iteration不用递归
// Time Complexity: O(h) h: 树高
// Space complexity: O(1) 
public TreeNode lca2(TreeNode root, TreeNode p, TreeNode q) {
    if(root == null) {
        return null;
    }
    while(root != null) {
        if(p.data < root.data && q.data < root.data) {    // p,q都在左子树
            return lca(root.left, p, q);
        }
        else if(p.data > root.data && q.data > root.data) {   // p,q都在右子树
            return lca(root.right, p, q);
        }
        else {        // p,q分别在不同子树
            break;
        }
    }
    return root;
}





Ref:

http://zhedahht.blog.163.com/blog/static/25411174201081263815813/

http://hawstein.com/posts/4.6.html

http://www.geeksforgeeks.org/lowest-common-ancestor-in-a-binary-search-tree/

【论文复现】Applied Intelligence 2025:Auto-PU正例无标签学习的自动化实现与GPT-5.4辅助编程实战 正例-无标签学习(Positive-Unlabelled Learning, PU Learning)是机器学习领域处理"只有正例标签,负例完全未知"场景的重要技术。本文基于2025年发表于Applied Intelligence的最新研究成果,详细阐述如何从零复现Auto-PU框架(包含GA-Auto-PU、BO-Auto-PU、EBO-Auto-PU三种优化器)。 阅读详情

相关推荐

【一文读懂】NTN(非地面网络)技术介绍

NTN,即非地面网络,是指利用卫星、高空平台(如无人机、平流层气球等)等非地面通信基础设施来实现全球通信覆盖的网络。在5G时代,NTN主要基于5G标准,特别是5G NR(New Radio)技术,通过卫星通信扩展地面网络的覆盖范围和服务能力。NTN技术的出现和发展,为全球通信带来了新的可能性和挑战。通过不断的技术创新和标准化推进,NTN有望在未来发挥更加重要的作用,为全球用户提供无处不在的通信服务。随着6G时代的到来,我们有理由相信NTN技术将迎来更加广阔的发展前景。

u011376987的博客 1万+

【数据结构与算法分析】0基础带你学数据结构与算法分析06--树(TREE)

Tree 是一些结点的集合,这个集合可以是空集;若不是空集,则 Tree 是由称为根的结点 r 以及零或多个非空的子树 T1,T2,⋯ ,​ 组成,这些子树的根都与 r 有一条有向边 (edge) 连接。这些子树的根被称为根 r 的孩子 (child),而 r 是这些 child 的父亲 (parent)。

感谢您的关注! 932

uni-app项目中引入Vant UI组件库(完美避坑!!!)纯净版

uni-app项目中引入Vant UI组件库(纯净版--无uni-ui)

Wzmlzrr的博客 3万+

【树论】最近公共祖先(LCA)

LCA(最近公共祖先)用于求树中两节点的 deepest 共同祖先。常用倍增法,预处理 O(n log n),查询 O(log n),核心是二进制跳跃与深度调整。

zhangmohan123321的博客 1522

YOLOv13添加OREPA模块 准确率提升10.56个点,map提升11.87个点。小目标轻量化

本文提出了一种新的OREPA(Optimal Recursive Edge-Preserving Attention)模块,通过结合递归和边缘保留注意力机制,显著提升了目标检测模型的性能。实验结果表明,添加OREPA模块后,准确率提升了10.56个百分点,mAP提升了11.87个百分点。OREPA模块包含三个核心组件:OREPA1处理特征图并保留边缘信息,Bottleneck_OREPA作为瓶颈模块降低计算量,OREPA类通过堆叠多个Bottleneck_OREPA增强网络表达能力。文章详细介绍了如何将OR

FJN110的博客 2761

上机任务一:空气质量指数 (air quality index,AQI是定量描述空气质量状况的指数。为了更好地了解和人们身体健康息息相关的天气状况,本书模拟生成500条某地区天气数据,一行样本对应一天

调整后的R平方为0.4308,考虑了模型中的自由度,它略低于多重R平方,说明模型的解释能力可能有限。总的来说,新的模型相对于之前的模型在AIC值上更优,包含了最高温度(X2)和最低温度(X3)这两个重要的预测因子,并且对AQI的解释能力较好。在表中,Df表示自由度,Sum Sq表示总平方和,Mean Sq表示均方(总平方和除以自由度),F value表示F统计量,Pr(>F)表示对应的p值。在分析这些结果时,需要关注系数的显著性(p值),系数的方向(正向或负向影响),以及系数的大小(估计值)。

Mrrunsen的博客 723

LCA算法以及原理详解

LCA-最近公共祖先   LCA(Least Common Ancestors),即最近公共祖先,这种描述是基于树结构的,也即我们通通常只在树结构中考虑祖先问题。树实际上就是图论中的有向无环图,而要研究LCA问题,首先我们要指定树中的一个顶点为根节点,并以该节点遍历有向无环图,生成一颗DFS序下的有向树,假设我们要查询的两个节点为u,v,DFS序下根节点到两点的最短路径分别是(r,u),和(r,v),LCA就是(r,u)与(r,v)公共路径的最后一个节点,如下图所示,w即为LCA。   换句话说,u,v的

qq_37957064的博客 2万+

基于扣子3.0复刻MIT“AI股神团队版”:实时股票数据API接入与策略选股复盘系统

基于扣子3.0的AI量化投资系统摘要 本文提出了一种基于扣子(Coze)3.0平台的AI量化投资解决方案,整合实时股票数据与策略选股功能。系统采用三层架构: 数据层:通过AKShare等开源工具获取A股实时行情和历史K线数据,支持批量数据抓取和清洗 策略层:内置多因子选股模型和技术指标分析模块,实现自动化标的筛选 应用层:利用扣子3.0的插件和工作流功能,构建从数据采集到投资建议的完整流程 系统特点包括:完全开源的数据接入方案、Python实现的策略计算模块、以及扣子平台提供的可视化编排能力~~~~~~~~

huanghm88的专栏 265

LCA的求法和扩展

LCA的求法和扩展求解树上LCA(最近公共祖先)11,朴素dfs(形象的说就是:爬!)22,在线:倍增跃迁33,tarjan:离线使用LCA最长树边的长度 求解树上LCA(最近公共祖先) 先上个友链:来自队长的极佳blog 11,朴素dfs(形象的说就是:爬!) 思路: 从两个点开始,先把深度更深的节点爬到两个节点相同的地步 两个节点一起上移,直到同一深度 过于直白,过程略 22,在线:倍增跃迁 规定:dep[0]=0dep[0]=0dep[0]=0(哨兵),默认lca第一个参的dep[x]dep[x]

qq_42852687的博客 348

ArcGIS Pro 3.4 二次开发 - 知识图谱

本文介绍了在ArcGIS Pro SDK 3.4和.NET 8环境下操作知识图谱的方法。主要包含两大功能模块:1) 知识图谱数据存储操作,包括建立连接、获取图层、检索要素类与表定义、ID转换等;2) 知识图谱数据模型管理,如获取数据模型属性、标识符信息等。代码示例详细展示了如何使用C#通过QueuedTask异步任务与知识图谱服务交互,包括异常处理、数据转换等常见操作场景。所有示例均采用using语句确保资源释放,并遵循ArcGIS Pro SDK的最佳实践。

Winemonk 763

相似贴子推荐:基于 LangChain4j + Milvus 的混合检索实战

本文提出了一种基于LangChain4j和Milvus的混合检索方案,用于解决论坛社区中的相似帖子推荐问题。该方案结合稠密向量语义检索和BM25关键词检索的优势,通过RRF算法实现结果融合。系统采用bge-small-zh模型生成语义向量,利用Milvus 2.5+原生支持的BM25功能和混合搜索API,在百万级数据规模下实现50ms内的检索延迟,召回率和精确率分别提升15%和22%。文章详细介绍了从数据预处理、向量化到混合检索的完整实现流程,并探讨了进阶优化方向,为推荐系统和RAG应用提供了高效解决方案。

分享AI、区块链技术及应用,未来已来 88

Tree[LCA模板]

LCA求公共祖先

Young_Zn_Cu 194

YOLO26涨点改进 | Conv篇/小目标改进 | AAAI 2025 FBRT-YOLO 两个轻量级FCM和MKP模块, 助力无人机航拍任务VisDrone、UAVDT和AI-TOD高效涨点

本文提出FBRT-YOLO26模型,通过引入两个轻量级模块FCM和MKP优化航拍图像检测性能。FCM模块通过特征互补映射解决小目标信息丢失问题,MKP模块利用多尺度卷积核增强目标感知能力。在VisDrone等数据集上的实验表明,该方法在精度和速度上均优于现有实时检测器。文章详细介绍了模块结构、核心代码实现及YAML配置文件修改方法,为航拍图像中的小目标检测提供了高效解决方案。该模型实现了检测精度与效率的良好平衡,具有实际应用价值。

Ai缝合怪、助力小伙伴高效发论文 369

vue中使用antv G6 的树图TreeGraph (紧凑树)①【新手学习向记录】

在vue中使用antv G6 树图,根据数据数值自定义节点。

yuryS的博客 9211

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Tree——LCA

题目描述: 题目背景: SOURCE:NOIP2015-SHY 给出一棵带有边权的树,问两点之间的距离。 输入格式: 第一行两个整数 n 和 m ,分别表示点数和询问数。 接下来 n-1 行,每行三个整数 x,y,z,表示 x 与 y 通过一条权为 z 的边连接。 接下来 m 行,每行两个整数 x,y,代表一组询问。 输出格式: 输出 m 行,每行一个整数,对应一组询问的答案。 样

千古的博客 314

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

最近公共祖先LCA问题

问题描述 求有根树的任意两个节点的最近公共祖先。 分析与解法 解答这个问题之前,咱们得先搞清楚到底什么是最近公共祖先。最近公共祖先简称LCA(Lowest Common Ancestor),所谓LCA,是当给定一个有根树T时,对于任意两个结点u、v,找到一个离根最远的结点x,使得x同时是u和v的祖先,x 便是u、v的最近公共祖先。(参见:http://en.wikipedia.o

Al_xin的专栏 2570

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

Leetcode 1483. Kth Ancestor of a Tree Node [Python]

这题这么理解,节点的数量不大于 50000, 按照最差情况下,这个tree是BST来做高度计算,当高度为16时,我们有2**16(= 65536 > 50000)个节点, 所以从root向下走,最多走15步到达最远的子节点,所以我们用全局常量self.step = 15来确定我们树的高度。同时我们计算2**step的距离下,各个节点的2**step距离的父节点,并存入self.parentlist中,则我们得到parentlist中的每个元素为一个字典,字典的index代表如果求某个节点的2**ind

sinat_30403031的博客 192

[复习]LCA Tree

题目背景 SOURCE:NOIP2015-SHY题目描述 给出一棵带有边权的树,问两点之间的距离。输入格式 第一行两个整数 n 和 m ,分别表示点数和询问数。 接下来 n-1 行,每行三个整数 x,y,z,表示 x 与 y 通过一条权为 z 的边连接。 接下来 m 行,每行两个整数 x,y,代表一组询问。输出格式 输出 m 行,每行一个整数,对应一组询问的答案。样例数据 输入 3

g19zwk的博客 322

Leetcode 1483. Kth Ancestor of a Tree Node 二进制思想or分布式思想

思想 如果每个结点,都保存了它所有的祖先结点,最终时间复杂度或者空间复杂度都会爆,导致无法通过测试样例 因此,想办法把O(n)O(n)O(n)变成O(log⁡n)O(\log n)O(logn)就能做出来了 让每个结点只保存一部分祖先,然后通过互相之间的关系,从而得到全部的信息 即,让每个结点保存它的第1,2,4,8…个祖先 代码 class TreeAncestor { public: vector<vector<int> > P; // P[i][node] ::::

Xurui_Luo的博客 387

树---求二叉搜索树中两节点的最低公共祖先(LCA)

一、问题描述给定二叉搜索树(BST)中两节点,找出他们的最低公共祖先。例如对于下图: LCA(4, 14)=8; LCA(8, 10)=8.二、问题求解利用BST的性质,从根节点从上自下递归遍历BST。假设n1,n2都在BST中,并且n1 < n2。 (1)在遍历过程中,遇到的第一个值介于n1和n2之间的节点n,也即n1 =< n <= n2, 就是n1和n2的LCA。 (2)在遍历过程中,如

爱橙子的OK绷的专栏 1705

Tree(可持久化字典树 树上区间 LCA)

original link - http://acm.hdu.edu.cn/showproblem.php?pid=4757 题意: 给出一棵点权树,每个查询要求出两个点之间的路径上的一个点,与给出的值异或最大。 解析: 区间单点异或===字典树 维护一个可持久化字典树,那么(x,y)(x,y)(x,y)分解为(x,lca)+(lca,y)(x,lca)+(lca,y)(x,lca)+(lca,y...

QAQ 521

Hard 单词变型成另一个单词 @CareerCup

对起始单词的每一个字母都做替换,把替换后的单词加入到queue中,并同时维护一个Map来记录变化前单词和变化后单词的联系。用来回溯时能打印出路径。 package Hard; import java.util.HashSet; import java.util.LinkedList; import java.util.Map; import java.util.Queue; impor

4761

Hard 找到由其它单词组成的最长单词 @CareerCup

用DFS的那个模板就能做出来,值得注意的是一个词必须被除自己外的其他词组成才行,不能是自己组成自己。 package Hard; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.HashMap; import CtCILibrary.A

3649

Tree_Graph 判断T2是否为T1的子树 @CareerCup

原文: You have two very large binary trees: T1, with millions of nodes, and T2, with hundreds of nodes. Create an algorithm to decide if T2 is a subtree of T1 译文: 有两棵很大的二叉树:T1有上百万个结点,T2有上百个结点。写

3487

Stack_Queue 把栈排序 Sort a stack @CareerCup

原文: Write a program to sort a stack in ascending order. You should not make any assumptions about how the stack is implemented. The following are the only functions that should be used to write thi

3231

Stack_Queue 猫狗队列问题 Cat dog queue @CareerCup

An animal shelter holds only dogs and cats, and operates ona strictly “first in, first out” basis. People must adopt either the “oldest”(based on arrival time) of all animals at the shelter, or they

3092
上一篇: Tree_Graph Inorder Successor in Binary Search Tree BST中找中序遍历的后继节点 @CareerCup
下一篇: Tree_Graph 判断T2是否为T1的子树 @CareerCup
chiiis
博客等级 码龄14年 422粉丝 429原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值