二叉树最近公共祖先问题(O(n) time 且只遍历一遍,O(1) Space (不考虑函数调用栈的空间))
来源:互联网 发布:淘宝粉丝怎么增加 编辑:程序博客网 时间:2024/06/05 09:11
问题:
找出二叉树中两个节点的最近公共祖先。
首先可以先参考下这个博客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;elsereturn 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;}}}}
1 0
- 二叉树最近公共祖先问题(O(n) time 且只遍历一遍,O(1) Space (不考虑函数调用栈的空间))
- Candy (分糖果),时间复杂度O(n),空间复杂度为O(1),且只需遍历一次的实现
- hihoCoder - 1062 - 最近公共祖先·一 (树的最近公共祖先问题!)
- 二叉树结点公共祖先 <O(logn)求解>
- morris 树的中序遍历(O(1)空间 O(n)时间)
- 二叉树-最近公共祖先(LCA)
- 二叉树最近公共祖先(LCA)
- 求一颗不含指向父节点指针的普通树中任意两个结点的最近公共祖先(O(N*N) 和 O(N) 算法)
- 二叉树的非递归遍历(不用栈、O(1)空间)
- 利用二叉树的非递归后序遍历求解最近公共祖先问题
- 习题4.5 顺序存储的二叉树的最近的公共祖先问题(25 分)
- 二叉树中的最近公共祖先问题
- 在二叉树中,求任意两个节点的最近公共祖先(遍历的应用算法)
- 二叉树的最近公共祖先
- 满二叉树的最近公共祖先
- 二叉树的最近公共祖先LCA
- Morris Traversal 方法遍历二叉树(非递归、不用栈,O(1)空间)
- Morris Traversal方法遍历二叉树(非递归,不用栈,O(1)空间)
- Java读写文本文件
- 结构性定义
- 资深Linux程序员的开发经验谈
- STL系列(9):容器适配器
- wcf和web service的区别
- 二叉树最近公共祖先问题(O(n) time 且只遍历一遍,O(1) Space (不考虑函数调用栈的空间))
- Settings分析
- Android4.4中的近场通讯(NFC)
- 4G PA.FLASH.套料手机平板通讯智能家居无人机大小物料大量现货供应!样品最新停产均有!
- 让技术改变生活 程序员的技术梦想
- 适应各浏览器图片裁剪无刷新上传js插件
- APK自我保护方法[转载]
- 黑马程序员---【C语言】04数组
- 非专业程序员谈程序员修炼之路