题目描述:
Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree.
According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes v and w as the lowest node in T that has both v and w as descendants (where we allow a node to be a descendant of itself).”
_______3______
/ \
___5__ ___1__
/ \ / \
6 _2 0 8
/ \
7 4
For example, the lowest common ancestor (LCA) of nodes 5 and 1 is 3. Another example is LCA of nodes 5 and 4 is 5, since a node can be a descendant of itself according to the LCA definition.
这就是找到从root到p和q的路径,找到他们最后一个相同的节点就是他们的父节点。
代码如下:
public class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
List<TreeNode> list1=new ArrayList<TreeNode>();
List<TreeNode> list2=new ArrayList<TreeNode>();
List<TreeNode> path1=new ArrayList<TreeNode>();
List<TreeNode> path2=new ArrayList<TreeNode>();
findPath(root, p, list1, path1);
findPath(root, q, list2, path2);
int i=0;
for(;i<path1.size()&&i<path2.size();i++){
if(path1.get(i)!=path2.get(i))
break;
}
return path1.get(i-1);
}
public void findPath(TreeNode root, TreeNode p ,List<TreeNode> list ,List<TreeNode> result){
if(root==p){
list.add(root);
result.addAll(list);
return;
}
if(root.left!=null){
list.add(root);
findPath(root.left, p, list, result);
list.remove(list.size()-1);
}
if(root.right!=null){
list.add(root);
findPath(root.right, p, list, result);
list.remove(list.size()-1);
}
}
}
之前findPath我是这么写的,这么做会超时,开销也太大。
public void findPath(TreeNode root, TreeNode p ,List<TreeNode> list ,List<TreeNode> result){
if(root==p){
list.add(root);
result.addAll(list);
return;
}
if(root.left!=null){
List<TreeNode> newlist1=new ArrayList<TreeNode>(list);
list.add(root);
findPath(root.left, p, newlist1, result);
}
if(root.right!=null){
List<TreeNode> newlist2=new ArrayList<TreeNode>(list);
newlist2.add(root);
findPath(root.right, p, newlist2, result);
}
}
我看别人还有一种递归,这种也是值得学习的:
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(root==null || p==null || q==null) return null;
List<TreeNode> pathp = new ArrayList<>();
List<TreeNode> pathq = new ArrayList<>();
pathp.add(root);
pathq.add(root);
getPath(root, p, pathp);
getPath(root, q, pathq);
TreeNode lca = null;
for(int i=0; i<pathp.size() && i<pathq.size(); i++) {
if(pathp.get(i) == pathq.get(i)) lca = pathp.get(i);
else break;
}
return lca;
}
private boolean getPath(TreeNode root, TreeNode n, List<TreeNode> path) {
if(root==n) {
return true;
}
if(root.left!=null) {
path.add(root.left);
if(getPath(root.left, n, path)) return true;
path.remove(path.size()-1);
}
if(root.right!=null) {
path.add(root.right);
if(getPath(root.right, n, path)) return true;
path.remove(path.size()-1);
}
return false;
}
本文介绍了一种求解二叉树中两节点最低公共祖先(LCA)的有效算法,并提供了两种实现方法,一种通过记录路径并寻找最后的共同节点,另一种采用递归方式简化过程。
442

被折叠的 条评论
为什么被折叠?



