Leetcode 236. Lowest common ancestor二叉树里的最近祖先问的 java实现和其衍生

Leetcode 236. Lowest common ancestor二叉树里的最近祖先问的java 实现

在这里插入图片描述
这道题其实就是要求我们找到两个给出节点的最近的父节点。我们可以利用分治法来处理,我们不断的在当前的节点向下寻找我们希望寻找的两个节点,如果找到了就返回找到的节点,如果同时找到两个节点就返回当前节点,因为当前节点就是我们希望寻找的lowest common ancestor(LCA). 让我们看看Java的实现吧。

class LCA{
	public TreeNode lca(TreeNode root,TreeNode p, TreeNode q){
		if(root == null || root == p || root == q) return root;
		TreeNode left = lca(root.left,p,q);
		TreeNode right = lca(root.right,p,q);
		if(left != null && right != null) return root;
		if(left != null) return left;
		if(right != null) return right;
		return null;
	}
}

让我们看一种比较特别的情况,就是当我们的TreeNode 结构中给了我们parentNode 话,我们应该怎么样来实现呢?用上面的方法当然也是可以的,但是怎么样利用给出的parentNode 来解决呢?我们首秀按利用两个数组来存储两个希望寻找的节点到根节点的路径,然后利用循环在这个这两个数组中找到最后一个一致的节点,这就是我们需要寻找的根节点了。

class LCA{
	public TreeNode lca(TreeNode root, TreeNode p, TreeNode q){
		ArrayList<> pathA= getPath(p);
		ArrayList<> pathB= getPath(q);
		TreeNode result = null;
        indexA = pathA.length()-1;
        indexB = pathB.length()-1;
        
        while(indexA >=0 && indexB >= 0){
            if(pathA.get(indexA) != pathB.get(indexB)){
                break;
            }
            result = pathA.get(indexA);
            indexA--;
            indexB--;
        }
        return result;
	}
	private ArrayList<TreeNode> getPath(TreeNode node){
		ArrayList<List> res = new ArrayList<>();
		while(node !=  null){
			res.add(node);
			node = node.parent;
		}
		return res;
	}
}

那如果我们面对的情况不保证着两个节点在同一棵树中呢?情况就又有了一些变化需要处理,我们在返回的时候就需要返回当前的树中是否找到了我们需要寻找的节点,以及是否存在LCA, 让我们看看java的实现吧!

class LCA{
	class ResultType{
    public boolean a_exist, b_exist;
    public TreeNode node;
    public ResultType(boolean a,boolean b,TreeNode node){
        this.a_exist = a;
        this.b_exist = b;
        this.node = node;
   	 }
	}
	public TreeNode lca(TreeNode root, TreeNode p, TreeNode q){
		Resulttype res = helper(root,p,q);
		return res.node;
	}
	private  ResultType helper(TreeNode root, TreeNode p, TreeNode q){
		if(root == null){
            return new ResultType(false,false,null);
        }
        ResultType left = helper(root.left,a,b);
        ResultType right = helper(root.right,a,b);
        boolean a_exist = left.a_exist||right.a_exist||root == a;
        boolean b_exist = left.b_exist||right.b_exist||root == b;
        if(root == a||root == b){
            return new ResultType(a_exist,b_exist,root);
        }
        if(left.node != null && right.node != null){
            return new ResultType(a_exist,b_exist,root);
        }
        if(left.node == null && right.node != null){
            return new ResultType(a_exist,b_exist,right.node);
        }
        if(left.node != null && right.node == null){
            return new ResultType(a_exist,b_exist,left.node);
        }
        return new ResultType(a_exist,b_exist,null);
	}
}

这样我们就可以很好的处理两个Node并不存在于同一棵树中的情况了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值