利用search tree的性质,在每个node上其实已经知道p和q分别在哪个child subtree。
对于一个node,以下三种情况可以直接确定该node就是LCA.
left里有一个target,root本身是一个target
right里有一个target, root本身是一个target
left, right里各有一个target
然后如果node不是LCA, 那么两个target要么都在left child, 要么都在right child.
所以只需要check其中的一边 (其实check的node都在一条确定的path上).
时间,空间复杂度都是O(h)
worst-case还是O(N), 如果tree是一条线。
import java.util.*;
public class Solution {
public int lowestCommonAncestor (TreeNode root, int p, int q) {
return findLCA(root, Integer.MIN_VALUE, Integer.MAX_VALUE, p, q);
}
int findLCA(TreeNode root, int min, int max, int p, int q) {
int numInLeft = root.left == null ? 0 : numInRange(min, root.val, p, q);
int numInRight = root.right == null ? 0 : numInRange(root.val, max, p, q);
// 三种情况下,root一定都是LCA
// a. left里有一个,root有一个
// b. right里有一个, root有一个
// c. left, right里各有一个
// 这个if其实涵盖了a,b,c三种情况
if (numInLeft == 1 || numInRight == 1)
return root.val;
else if (numInLeft == 2)
return findLCA(root.left, min, root.val, p, q);
else // numInRight == 2
return findLCA(root.right, root.val, max, p, q);
}
// Helper function that determines how many targets are in (min, max) - 左开右开
int numInRange(int min, int max, int p, int q) {
if ((p > min && p < max) && (q > min && q < max))
return 2;
if ((p > min && p < max) || (q > min && q < max))
return 1;
else
return 0;
}
}