二元最近的共同祖先问题(O(n) time 而且,只有一次遍历,O(1) Space (它不考虑函数调用栈空间))
问题:
找到两个节点的二叉树的最近的共同祖先。
首先可以参考这个博客http://blog.csdn.net/cxllyg/article/details/7635992 ,写的比較具体,包含了节点包含父指针和不包含父指针的情况,还介绍了经典的Tarjan算法。
Tarjan算法非常精妙,可是使用了并查集,须要额外O(n)的存储空间。
上面博客中给的第三个方法也是须要记录根到节点的路径,须要O(log n)空间,当然考虑到普通情况下我们遍历树都是递归的方式。所以本身方法调用栈就是O(log
n)空间占用率。 可是这是对于平衡的二叉树而言的。在最差情况下空间占用率还是O(n)。
所以。这里我给的算法不须要记录根到节点的路径。并且只遍历树一遍就能够完毕。
1. 首先深度遍历树,找到第一个节点,如果为p。这时设置两个节点的近期公共祖先为p
2. 继续深度遍历,找另外一个节点q, 如果这时找到q, 那么二者近期祖先就是p.
3. 否则,回退到上一层,这时二者的近期公共祖先也对应改成了p的父节点。由于以p为根的子树中没有发现另外一个节点q
4. 依此类推。找不到则继续回退到上一层,当找到q时,相应的二者近期公共祖先也就找到了。
5. 若是p==q,直接返回p作为近期公共祖先
6. 若二者不都存在于树中,则返回空。
public class CommonAncestor {
public static void main(String[] args) {
CommonAncestor ca=new CommonAncestor();
TreeNode root=new TreeNode(0);
TreeNode l1=new TreeNode(-1);
TreeNode r1=new TreeNode(1);
root.left=l1;
root.right=r1;
TreeNode l1l1=new TreeNode(-2);
TreeNode l1r1=new TreeNode(-3);
l1.left=l1l1;
l1.right=l1r1;
TreeNode r=ca.commonAncestor(root, l1, r1);
System.out.println(r.val);
}
private TreeNode ancestor=null;
private TreeNode firstFound=null;
private boolean found=false;
public CommonAncestor()
{
}
public TreeNode commonAncestor(TreeNode root,TreeNode p,TreeNode q)
{
this.ancestor=null;
this.found=false;
findCommonAncestor(root,p,q);
if(found)
return ancestor;
else
return null;
}
private void findCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(root==null)
return ;
if(found)
return;
this.findCommonAncestor(root.left, p, q);
test(root,p,q);
this.findCommonAncestor(root.right, p, q);
test(root,p,q);
}
private void test(TreeNode root, TreeNode p, TreeNode q) {
if(found)
return;
if(this.ancestor==null)
{
if(root==p)
{
this.ancestor=p;
firstFound=p;
if(p==q)
found=true;
}
else if(root==q)
{
this.ancestor=q;
firstFound=q;
if(p==q)
found=true;
}
}
else
{
if(root.left==this.ancestor||root.right==this.ancestor)
{
this.ancestor=root;
}
if((root==p||root==q)&&root!=firstFound)
{
found=true;
}
}
}
}
版权声明:本文博主原创文章。博客,未经同意不得转载。
二元最近的共同祖先问题(O(n) time 而且,只有一次遍历,O(1) Space (它不考虑函数调用栈空间))的更多相关文章
- LCA 学习算法 (最近的共同祖先)poj 1330
Nearest Common Ancestors Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 20983 Accept ...
- 二叉树系列 - 求两节点的最低公共祖先,例 剑指Offer 50
前言 本篇是对二叉树系列中求最低公共祖先类题目的讨论. 题目 对于给定二叉树,输入两个树节点,求它们的最低公共祖先. 思考:这其实并不单单是一道题目,解题的过程中,要先弄清楚这棵二叉树有没有一些特殊的 ...
- 最近公共祖先 LCA Tarjan算法
来自:http://www.cnblogs.com/ylfdrib/archive/2010/11/03/1867901.html 对于一棵有根树,就会有父亲结点,祖先结点,当然最近公共祖先就是这两个 ...
- hdu 2586(最近公共祖先LCA)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 思路:在求解最近公共祖先的问题上,用到的是Tarjan的思想,从根结点开始形成一棵深搜树,非常好 ...
- 求职之C++小知识点整理
1.顺序容器 1.顺序容器:vector,deque,list,forward_list,array,string.其中除list和forward_list外,其它都支持快速随机访问. deque a ...
- 岛屿的个数12 · Number of Islands12
[抄题]: 给一个01矩阵,求不同的岛屿的个数. 0代表海,1代表岛,如果两个1相邻,那么这两个1属于同一个岛.我们只考虑上下左右为相邻. [ [1, 1, 0, 0, 0], [0, 1, 0, 0 ...
- 07. Go 语言接口
Go 语言接口 接口本身是调用方和实现方均需要遵守的一种协议,大家按照统一的方法命名参数类型和数量来协调逻辑处理的过程. Go 语言中使用组合实现对象特性的描述.对象的内部使用结构体内嵌组合对象应该具 ...
- LCA算法的理解
LCA思想: 在求解最近公共祖先为问题上,用到的是Tarjan的思想,从根结点开始形成一棵深搜树,非常好的处理技巧就是在回溯到结点u的时候,u的子树已经遍历,这时候才把u结点放入合并集合中, 这样u结 ...
- poj1330Nearest Common Ancestors 1470 Closest Common Ancestors(LCA算法)
LCA思想:http://www.cnblogs.com/hujunzheng/p/3945885.html 在求解最近公共祖先为问题上,用到的是Tarjan的思想,从根结点开始形成一棵深搜树,非常好 ...
随机推荐
- WPF界面设计技巧(11)-认知流文档 & 小议WPF的野心
原文:WPF界面设计技巧(11)-认知流文档 & 小议WPF的野心 流文档是WPF中的一种独特的文档承载格式,它的书写和呈现方式都很像HTML,它也几乎具备了HTML的绝大多数优势,并提供了更 ...
- SWT入门-常用组件的使用(转)
转自:http://www.cnblogs.com/kentyshang/archive/2007/08/16/858367.html swt的常用组件button ,text ,combo,list ...
- CSS之box-sizing的用处简介
前几天才发现有 box-sizing 这么个样式属性.研究了一番感觉非常有意思, 通过指定容器的盒子模型类型,达到不同的展示效果 比如:当一个容器宽度定义为 width:100%; 之后.假设再添加 ...
- UNIX网络编程卷1 server程序设计范式7 预先创建线程,以相互排斥锁上锁方式保护accept
本文为senlie原创.转载请保留此地址:http://blog.csdn.net/zhengsenlie 1.预先创建一个线程池.并让每一个线程各自调用 accept 2.用相互排斥锁代替让每一个线 ...
- 主流芯片解决方案Ambarella的高清网络摄像机、德州仪器和控制海思
(本文由四川艾普作为数码科技有限公司 苏斌.范清华 收集) 高清网络视频监控发展到今天.正的高清时代.诸多有实力的高清摄像机厂家的产品线也逐渐完好起来,高清网络视频监控的配套产品有更加丰富和成熟.与此 ...
- Tomcat7.0设置虚拟文件夹
(1)眼下,我们的网站网站都是放在默认的文件夹下:tomcat/webapps/下的.可是,在某种情况下.我们须要把网站放到其它的文件夹,比方:tomcat所在磁盘的空间不足: 或者为了项目的统一管理 ...
- Java实现字符全阵列阵列
import org.junit.Test; public class AllSort { public void permutation(char[] buf, int start, int end ...
- sql server 远程
资讯 | 安全 | 论坛 | 下载 | 读书 | 程序开发 | 数据库 | 系统 | 网络 | 电子书 | 站长学院 | 源码 | QQ | 专栏 | 考试 | 手册 | ...
- tcpdump VS tshark用法(转)
Tcpdump是网络协议分析的基本工具.tshark是大名鼎鼎的开源网络协议分析工具wireshark (原名叫ethereal)的命令行版本,wireshark可对多达千余种网络协议进行解码分析.W ...
- 【iOS开发-60】案例学习:多组数据的tableView设置、添加右側组索引、多层数据模型设置以及valueForKeyPath
效果: 这里的数据模型有两层:每一组汽车是一层模型,每一组里面的每一行汽车品牌也是一层模型. (1)我们先创建一个WSCars模型. 在WSCars.h中: #import <Foundatio ...