解题思路:将到达p和q的节点的路径保存到集合里,然后再遍历两个集合,返回集合中最后相等的值就是最近的公共祖先。时间复杂度O(N),空间复杂度O(N)。
import java.util.*;
/*
* public class TreeNode {
* int val = 0;
* TreeNode left = null;
* TreeNode right = null;
* public TreeNode(int val) {
* this.val = val;
* }
* }
*/
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param root TreeNode类
* @param p int整型
* @param q int整型
* @return int整型
*/
public int lowestCommonAncestor (TreeNode root, int p, int q) {
// write code here
//在二叉搜索树中查找到p和q的路径,并保存起来
ArrayList<Integer> qList = new ArrayList<>();
ArrayList<Integer> pList = new ArrayList<>();
addtoList(root, qList, q);
addtoList(root, pList, p);
int size = Math.min(qList.size(), pList.size());
int result = 0;
//找出二叉搜索树中最后一个相等的数就是最近的公共祖先
for (int i = 0; i < size; i++) {
if (qList.get(i).equals(pList.get(i))) {
result = qList.get(i);
}
}
return result;
}
private void addtoList(TreeNode root, ArrayList<Integer> list, int x) {
if (root.val == x) {
list.add(x);
}
if (root.val < x) {
list.add(root.val);
addtoList(root.right, list, x);
}
if (root.val > x) {
list.add(root.val);
addtoList(root.left, list, x);
}
}
}
解法二:递归,如果当前值都比p和q大,那么公共节点一定在左子树,继续遍历左子树并返回,如果当前值都比p和q小,那么公共节点一定在右子树,继续遍历右子树并返回,如果不是上述两种情况,要么有=root.val的,要么一个大于root.val一个小于root.val,这种都返回root。时间复杂度O(N),空间复杂度O(1)。
import java.util.*;
/*
* public class TreeNode {
* int val = 0;
* TreeNode left = null;
* TreeNode right = null;
* public TreeNode(int val) {
* this.val = val;
* }
* }
*/
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param root TreeNode类
* @param p int整型
* @param q int整型
* @return int整型
*/
public int lowestCommonAncestor (TreeNode root, int p, int q) {
// write code here
return lowestCommonAncestor2(root, p, q).val;
}
private TreeNode lowestCommonAncestor2(TreeNode root, int p, int q) {
if (p < root.val && q < root.val) {
//公共祖先肯定在左子树
return lowestCommonAncestor2(root.left, p, q);
} else if (p > root.val && q > root.val) {
//公共祖先肯定在右子树
return lowestCommonAncestor2(root.right, p, q);
} else {
//目前节点就是公共祖先
return root;
}
}
}