题目
解题
因为二叉搜索树的性质,235题会比较容易解答,进阶版本:LeetCode236 二叉树的最近公共祖先 &《程序员面试金典》面试题 04.08. 首个共同祖先。
解题一:一次遍历
// javascript
var lowestCommonAncestor = function(root, p, q) {
if (root === null) return null;
// if (p === root || q === root) return root; // 可以省略,else 能够 handle
if (p.val > root.val && q.val > root.val) return lowestCommonAncestor(root.right, p, q);
else if (p.val < root.val && q.val < root.val) return lowestCommonAncestor(root.left, p, q);
else return root;
};
换一种写法:
// javascript
var lowestCommonAncestor = function(root, p, q) {
if (root === null) return null;
if (root === p || root === q) return root; // 必须有
const pIsOnLeft = (p.val < root.val);
const qIsOnLeft = (q.val < root.val);
if (pIsOnLeft !== qIsOnLeft) return root;
const next = pIsOnLeft ? root.left : root.right;
return lowestCommonAncestor(next, p, q);
};
也可以不用递归:
// javascript
var lowestCommonAncestor = function(root, p, q) {
let ancestor = root;
while (ancestor !== null) {
if (p.val > ancestor.val && q.val > ancestor.val) ancestor = ancestor.right;
else if (p.val < ancestor.val && q.val < ancestor.val) ancestor = ancestor.left;
else break;
}
return ancestor;
};
解题二:两次遍历
// javascript
var lowestCommonAncestor = function(root, p, q) {
const pathP = getPath(root, p);
const pathQ = getPath(root, q);
const len = Math.min(pathP.length, pathQ.length);
let ancestor = null;
for (let i = 0; i < len; i++) {
if (pathP[i] === pathQ[i]) ancestor = pathP[i];
else break;
}
return ancestor;
};
const getPath = (root, target) => {
const path = new Array();
while (root !== target) {
path.push(root);
if (target.val < root.val) root = root.left;
else root = root.right;
}
path.push(target);
return path;
};