2021/05/05
求出两个 path
找两个 path 中最后一次连续相同的位置。
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
List<TreeNode> a = getPath(root, p.val);
List<TreeNode> b = getPath(root, q.val);
int i = 0;
while (i < a.size() && i < b.size() && a.get(i).val == b.get(i).val) {
i += 1;
}
return a.get(i - 1);
}
List<TreeNode> getPath(TreeNode root, int target) {
if (root.val == target) {
LinkedList<TreeNode> path = new LinkedList<>();
path.add(root);
return path;
}
List<TreeNode> path = getPath(root.val < target ? root.right : root.left, target);
path.add(0, root);
return path;
}
}
求 path 的代码可以改成递推的
class Solution {
public List<TreeNode> getPath(TreeNode root, TreeNode target) {
List<TreeNode> path = new ArrayList<TreeNode>();
TreeNode node = root;
while (node != target) {
path.add(node);
if (target.val < node.val) {
node = node.left;
} else {
node = node.right;
}
}
path.add(node);
return path;
}
}
一次遍历
从根节点开始向下搜索,当某个结点的值处于两个结点中间时,就是最近公共祖先。
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
TreeNode low, high;
if (p.val > q.val) {
low = q;
high = p;
} else {
low = p;
high = q;
}
while (true) {
if (root.val > high.val) {
root = root.left;
} else if (root.val < low.val) {
root = root.right;
} else {
return root;
}
}
}
}
评论区看到一个一行的解法:
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
return (root.val - p.val) * (root.val - q.val) <= 0 ? root : lowestCommonAncestor(p.val < root.val ? root.left : root.right, p, q);
}
}