解题思路:这题主要是保存o1->根节点的路径,o2->根节点的路径,现将部分节点的值和其父节点的值保存到map里,这里所说的部分是指保存到出现到o1和o2即可,然后就直接从map里找父节点的父节点,一直到根结点。时间复杂度O(N),空间复杂度O(N)。
import java.util.*;
/*
* public class TreeNode {
* int val = 0;
* TreeNode left = null;
* TreeNode right = null;
* }
*/
public class Solution {
/**
*
* @param root TreeNode类
* @param o1 int整型
* @param o2 int整型
* @return int整型
*/
public int lowestCommonAncestor (TreeNode root, int o1, int o2) {
// write code here
//声明一个Map来保存每个节点的父节点
Map<Integer, Integer> map = new HashMap<>();
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
//将根节点的父节点设置为-1;
map.put(root.val, -1);
//只要map包含o1和o2就可以退出循环了,不用遍历整棵树
while (!(map.containsKey(o1) && map.containsKey(o2))) {
TreeNode node = queue.poll();
if (node.left != null) {
queue.offer(node.left);
map.put(node.left.val, node.val);
}
if (node.right != null) {
queue.offer(node.right);
map.put(node.right.val, node.val);
}
}
//set保存o1->根节点的所有值
Set<Integer> set = new HashSet<>();
set.add(o1);
while (map.get(o1) != -1) {
o1 = map.get(o1);
set.add(o1);
}
while (!set.contains(o2)) {
o2 = map.get(o2);
}
return o2;
}
}
解法二:递归,需要遍历每个节点,递归调用的时候要保存每个节点是否包含o1或者o2,因此时间复杂度O(N),空间复杂度O(N)。
import java.util.*;
/*
* public class TreeNode {
* int val = 0;
* TreeNode left = null;
* TreeNode right = null;
* }
*/
public class Solution {
/**
*
* @param root TreeNode类
* @param o1 int整型
* @param o2 int整型
* @return int整型
*/
public int lowestCommonAncestor (TreeNode root, int o1, int o2) {
// write code here
return lowestCommonAncestor2(root, o1, o2).val;
}
//该方法表示当节点为node的时候,返回node这棵树上,o1和o2的最近公共祖先
private TreeNode lowestCommonAncestor2(TreeNode node, int o1, int o2){
if(node == null || node.val == o1 || node.val == o2){
return node;
}
//左子树返回的公共祖先
TreeNode left = lowestCommonAncestor2(node.left, o1, o2);
//右子树返回的公共祖先
TreeNode right = lowestCommonAncestor2(node.right, o1, o2);
//如果左子树上没有一个值等于o1或者o2,因此在左子树上没有公共祖先,此时就返回右子树
if(left == null){
return right;
}
//如果右子树上没有一个值等于o1或者o2,因此在右子树上没有公共祖先,此时就返回左子树
if(right == null){
return left;
}
//如果左右子树都不为空,说明一个在在左子树,一个在右子树,当前节点就是公共祖先,返回node
return node;
}
}