题目链接:https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-search-tree/
分析:
- 观察:在二叉搜索树中,任意两个节点都有且只有一个公共祖先。因此,只要找到这个公共祖先,便找到了这两个节点的最近公共祖先;
- 观察:在二叉搜索树中,恒有如下关系:
左子节点的值 < 根节点的值 < 右子节点的值 \text{左子节点的值} < \text{根节点的值} < \text{右子节点的值} 左子节点的值<根节点的值<右子节点的值
因此,我们可以用“夹挤准则”来找两个子节点的公共祖先:假设左子节点和右子节点的值形成了一个区间[]
,那么- 当根节点的值落到这个区间左侧时,我们就把根节点往右移动(根据二叉搜索树的规则,往右移动会使节点的值变大);
- 当根节点的值落到区间的右侧时,就把根节点往左移动;
- 当有一天根节点落到区间内部时,我们便找到了这两个节点的一个公共祖先。根据前面观察到的二叉树公共祖先的唯一性,这个公共祖先便是我们最终要找的两个节点的最近公共祖先。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
TreeNode *cur = root;
while (true) {
if ((cur->val < p->val) && (cur->val < q->val)) // 根节点的值落到了区间左侧
cur = cur->right;
else if ((cur->val > p->val) && (cur->val > q->val)) // 根节点的值落到了区间右侧
cur = cur->left;
else // 找到了公共祖先
break;
}
return cur;
}
};