剑指 Offer 68 - I. 二叉搜索树的最近公共祖先
什么是二叉搜索树
二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树。二叉搜索树作为一种经典的数据结构,它既有链表的快速插入与删除操作的特点,又有数组快速查找的优势。
重点特性:
- 当前节点的值大于其所有左子树节点的值,而小于其所有右子树结点的值
解法
方法一:递归
- 如果两个结点的值一个比根节点(当前查找的结点)的值小,另一个比根节的值点大,则根节点就是两个指定节点的最近公共祖先。(递归出口)
- 如果两个结点的值都比根节点(当前查找的结点)的值小,则直接在该节点的左子树上寻找。
- 如果两个结点的值都比根节点(当前查找的结点)的值大,则直接在该节点的右子树上寻找。
【代码】
/**
* @param {TreeNode} root
* @param {TreeNode} p
* @param {TreeNode} q
* @return {TreeNode}
*/
var lowestCommonAncestor = function(root, p, q) {
if (root.val > p.val && root.val > q.val) {
return lowestCommonAncestor(root.left, p, q)
} else if(root.val < p.val && root.val < q.val) {
return lowestCommonAncestor(root.right, p, q)
}
return root
};
方法二:迭代
- 当 p, qp,q 都在 rootroot 的 右子树 中,则遍历至 root.rightroot.right ;
- 否则,当 p, qp,q 都在 rootroot 的 左子树 中,则遍历至 root.leftroot.left ;
- 否则,说明找到了 最近公共祖先 ,跳出。
【代码】
/**
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
/**
* @param {TreeNode} root
* @param {TreeNode} p
* @param {TreeNode} q
* @return {TreeNode}
*/
var lowestCommonAncestor = function(root, p, q) {
let min = Math.min(p.val, q.val)
let max = Math.max(p.val, q.val)
let ret = root
while(root !== null) {
if(root.val > max){
root = root.left
}else if(root.val < min) {
root = root.right
}else{
ret = root
break
}
}
return ret
};