非搜索二叉树的最近公共祖先

该博客探讨了如何在不允许使用额外空间的情况下,解决非搜索二叉树中寻找两个节点的最近公共祖先问题。通过从根节点开始遍历,根据节点在左右子树中的分布情况,递归地确定最近公共祖先。
摘要由CSDN通过智能技术生成
 今天做了一个在线编程题,
 题目是:求一个一般二叉树(非二叉搜索树)的最近公共祖先。

题目要求不能使用额外空间来存储节点。


与二叉搜索树不同的是,每个叶子节点的数值value是没有规律的,

这就没有办法用什么乘2除2来做了。


解法的思路是:

* 从根节点开始遍历,如果node1和node2分别在root的左子树和右子树中,
 * 那么根节点就是node1和node2的最近公祖先。
 * 如果node1和node2都在左子树/右子树中,则递归左子树/右子树,
 * 直到找到他们的最近公共节点。
 

/**
 * 
 */
package dianer;

/** 
*  @author   LilyLee
 * @date     2017年3月22日
 * @time     下午5:08:43
 * @Version  1.0
 * @email    lilylee_1213@foxmail.com
 *
 */

/*
 * 
 * 今天做了一个在线编程题,
 * 题目是:求一个一般二叉树(非二叉搜索树)的最近公共祖先。
 * 题目要求不能使用额外空间来存储节点。
 * 
 * 解法思路:
 * 从根节点开始遍历,如果node1和node2分别在root的左子树和右子树中,
 * 那么根节点就是node1和node2的最近公祖先。
 * 如果node1和node2都在左子树/右子树中,则递归左子树/右子树,
 * 直到找到他们的最近公共节点。
 * 
 * 
 * 
 * */

public class TreeLCA {
	
	public static void main(String[] args) {
		TreeLCA t = new TreeLCA();
		t.test();
		
	}
	

	public class Node{
		public int data;
		public Node left;
		public Node right;
		
		Node(){}
		Node(int data){this.data = data;}
	}

	public  Node findLCA(Node root, Node n1, Node n2) {
		
		if( root == null) //没找到
			return null;
		
		if(root.data == n1.data || root.data == n2.data) //找到
			return root;
		
		Node L = findLCA(root.left, n1, n2); //在左子树找
		Node R = findLCA(root.right, n1, n2); //在右子树找
		
		//当前结点左右子树都找到了n1和n2,那么这个结点就是LCA结点
		if( L != null && R != null) {
			return root;
		}else {
			return L != null ? L : R;
		}
	
		
/*		
		if(L!=null){
			if(R!=null){
				return root;
			}else return L;
			
		}
		
		else {
			if(L!=null){
				return root;
			}else return R;
			
		}
		
*/		
		
	
	}
	

		
		

	//测试
	public void test(){
		Node[] A = new Node[20];
		
		for(int i = 1; i < 20; i++) {
			A[i] = new Node(i);
		}
		
		for (int i = 1; i < 8; ++i) {  
			A[i].left = A[i * 2 ];    
			A[i].right = A[i * 2 + 1];  
		}  
		/*              1
		 *         2         3
		 *      4    5     6     7
		 *    8  9 10 11 12 13 14 15
		 * 
		 */	
		
		
		
		Node ancestor = findLCA(A[1], A[12], A[11]);
		if(ancestor==null) System.out.println("Not exist!");
		else System.out.println("最近公共父节点为:"+ancestor.data);
	}
	

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值