二叉树两结点的最低共同父结点

声明:本片文章为阅读何海涛网易日志后,自己用java实现后的学习总结。

何海涛日志:二叉树两结点的最低共同父结点

题目:输入二叉树中的两个结点,输出这两个结点在数中最低的共同父结点。

思路:方法一:用递归

   方法二:找到从根节点分别到达两个节点的路径链表,然后再查找两个链表离根节点最远的公共节点,即我们的结果。

   两种方法思路都很清晰,所以不多做陈述,下面上代码.

代码:

/**
 * 题目:输入二叉树中的两个结点,输出这两个结点在数中最低的共同父结点。
 * @author hongbin.gao
 *
 */

public class LastCommonParent {
	public static void main(String[] args){
		TreeNode root = new TreeNode(1);
		TreeNode p1 = new TreeNode(2);
		TreeNode p2 = new TreeNode(3);
		TreeNode p3 = new TreeNode(4);
		TreeNode p4 = new TreeNode(5);
		
		TreeNode p5 = new TreeNode(6);
		
		root.left = p1;  root.right = p2;
		p1.left = p3;  p1.right = p4;
		p2.left = p5;p2.right = null;
		p3.left = p3.right = null;
		p4.left = p4.right = null;
		p5.left = p5.right = null;
		
		TreeNode lastParent = lastCommonParent_2(root,p3,p2);
		System.out.println(lastParent.val);
	}
	/**
	 * 方法一:用普通递归的方式。
	 * @param root
	 * @param p1
	 * @param p2
	 * @return
	 */
	public static TreeNode lastCommonParent_1(TreeNode root, TreeNode p1, TreeNode p2){ //在以root为根的二叉树中寻找p1,p2的共同最低父节点。
		if(root == null)
			return null;
		if(p1 == null && p2 != null)
			return p2;
		if(p1 != null && p2 == null)
			return p1;
		
		if(hasNode(root.left,p1) && hasNode(root.left,p2))
			return lastCommonParent_1(root.left,p1,p2);
		else if(hasNode(root.right, p1) && hasNode(root.right,p2))
			return lastCommonParent_1(root.right,p1,p2);
		else
			return root;
	}
	
	public static boolean hasNode(TreeNode root, TreeNode pNode){ //判断pNode是否在以root为根的二叉树中。
		if(root == null && pNode != null)
			return false;
		if(pNode == null)
			return true;
		
		if(root == pNode)
			return true;
		
		if(hasNode(root.left,pNode) || hasNode(root.right,pNode))
			return true;
		else 
			return false;
	}
	
	/**
	 * 因为方法一使用递归,在对二叉树进行遍历时,会有很多重复的计算,所以时间复杂度较低。
	 * 方法二:如果可以分别从p1,p2出发,找到一条指向root的链表,则我们只需要分析p1--->root和p2--->root的第一个公共节点即可。
	 * 这样虽然空间复杂度多一些,但是时间复杂度降为O(n),是非常可取的。
	 * @param root
	 * @param p1
	 * @param p2
	 * @return
	 */
	public static TreeNode lastCommonParent_2(TreeNode root, TreeNode p1, TreeNode p2){
		LinkedList<TreeNode> linkedList1 = new LinkedList<TreeNode>();
		LinkedList<TreeNode> linkedList2 = new LinkedList<TreeNode>();
		
		boolean flag1 =  linkedTree(root, p1, linkedList1);
		boolean flag2 = linkedTree(root, p2, linkedList2);
		
        int length1 = linkedList1.size();
        int length2 = linkedList2.size();
        int i=0;
        if(length1 <= 0 || length2 <=0)
        	return null;
        
        TreeNode common =null; 
        while(i<length1 && i<length2 && linkedList1.get(i) == linkedList2.get(i)){
        	common = linkedList1.get(i);
        	i++;
        }
        
        return common;
	}
	
	public static boolean linkedTree(TreeNode root, TreeNode p, LinkedList<TreeNode> linkedList){
		Stack<TreeNode> stack = new Stack<TreeNode>();
		TreeNode temp = null;
		if(root == null)
			return false;
		
		if(p == null)
			return true;
		
		if(root == p){
			linkedList.add(root);
			return true;
		}
		
		if(root != null){
			linkedList.add(root);
			boolean flag = linkedTree(root.left,p,linkedList);
	        if(flag)
	        	return true;
	        else{
	        	if(root.left != null){
	        	   linkedList.removeLast();  //如果左子树不行,则退出来,检测右子树。
	        	   flag = linkedTree(root.right,p,linkedList);
	        	}
	        	else{
	        		flag = linkedTree(root.right,p,linkedList);
	        	}
	        	if(flag)
	        		return true;
	        	else{
	        		if(root.right != null)
	        			linkedList.removeLast();
	        	return false;
	        	}
	        }
		}
		return false;
	}
	
}




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值