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并不存在于同一棵树中的情况了。