Cracking the coding interview--Q4.6

题目

原文:

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.

译文:

设计算法并写代码在一个二叉树中找出两个结点的第一个共同祖先。避免存储额外的结点。注意:这里不特指二叉查找树。

解答

若使用额外的存储空间,最简单的方式就是对于一个结点向父节点进行遍历,直至根结点。可以考虑存储为hash,然后对另一个结点向父节点进行遍历,同时和第一个结点的父节点,所组成的hash集合进行比较,第一个相同的结点即为二者的共同祖先;

若不能使用额外的存储空间,则只能是不断的取一个节点的父节点,然后同另外一个节点的所有父节点进行比较,直到根节点;

另外如果节点没有父指针,那么则需要从根节点开始遍历,依次判断每个节点,是否可以到达问题中的两个节点。找到最后一个这样的节点即可

代码如下:

import java.util.HashSet;

class Q4_6{
	public static TreeNode ancestor;
	//使用额外的空间存储
	public static TreeNode method1(TreeNode tn1,TreeNode tn2){
		if(tn1==null||tn2==null) return null;
		HashSet<TreeNode> set=new HashSet<TreeNode>();
		while(tn1.parent!=null){
			set.add(tn1);
			tn1=tn1.parent;
		}
		while(tn2.parent!=null){
			if(set.contains(tn2))
				return tn2;
			tn2=tn2.parent;
		}
		return null;
	}
	//不使用额外的空间
	public static TreeNode method2(TreeNode tn1,TreeNode tn2){
		if(tn1==null||tn2==null) return null;
		for(TreeNode p=tn1;p!=null;p=p.parent){
			TreeNode q=tn2;
			while(q.parent!=null){
				if(q==p)
					return q;
				q=q.parent;
			}
		}
		return null;
	}
	//不存在父指针的节点
	//ancestor会不断更新,直到最后一个共同的祖先
	public static void method3(TreeNode tn1,TreeNode tn2,TreeNode head){
		if(head==null||tn1==null||tn2==null) return;
		if(head!=null&&father(head,tn1)&&father(head,tn2)){
			ancestor=head;
			method3(tn1,tn2,head.lchild);
			method3(tn1,tn2,head.rchild);
		}
	}
	private static boolean father(TreeNode head,TreeNode tnode){
		if(head==null) return false;
		else if(head==tnode) return true;
		else return father(head.rchild,tnode)||father(head.lchild,tnode);
	}
	
	public static void main(String[] args){
		int[] arr={6,3,8,7,4,9};
		TreeNode root = TreeNode.createBinaryTree(arr);
		TreeNode tn1 = root.rchild.lchild;
		TreeNode tn2 = root.rchild.rchild;
		System.out.println(method1(tn1,tn2).value);
		System.out.println(method2(tn1,tn2).value);
		
		method3(tn1,tn2,root);
		System.out.println(ancestor.value);
	}
}

class TreeNode{
	int value;
	TreeNode lchild;
	TreeNode rchild;
	TreeNode parent;
	
	public static void insert(TreeNode tnode,int x,TreeNode p){
		if(tnode==null){
			tnode=new TreeNode();
			tnode.value=x;
			tnode.lchild=null;
			tnode.rchild=null;
			if(p.value>x)
				p.lchild=tnode;
			else
				p.rchild=tnode;
			tnode.parent=p;
			return;
		}
		
		if(x<tnode.value){
			insert(tnode.lchild,x,tnode);
		}else{
			insert(tnode.rchild,x,tnode);
		}
	}
	
	public static TreeNode createBinaryTree(int[] values){
		TreeNode root=new TreeNode();
		root.value=values[0];
		for(int i=1;i<values.length;i++){
			insert(root,values[i],root);
		}
		return root;
	}
}

---EOF---



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值