题目描述
给定一课二叉查找树 (BST),找到其中指定两个点的最近公共祖先 (LCA)。
根据 Wikipedia 中 LCA的定义 :“最近公共祖先定义为两个结点 p 和 q 之间,树中最低的结点同时拥有 p 和 q 作为后代(这里允许一个结点的后代为它本身)。
样例
输入:root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8
输出:6
解释:结点 2 和结点 8 的最近公共祖先是 6。
输入:root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4
输出:2
解释:结点 2 和结点 4 的最近公共祖先是 2, 因为根据定义最近公共祖先结点可以为结点本身。
注意
- 树中每个结点的权值都是唯一的。
- p 和 q 是两个不同的结点,且其值必定在 BST 中出现。
算法
(暴力) $O(h)$
- 由于这是一棵二叉查找树,我们可以利用二叉查找树的性质来从根结点开始寻找。
- 首先根结点必定是候选公共祖先,接着如果 p 和 q 同时出现在左子树,则我们往左儿子移动;如果 p 和 q 同时出现在右子树,则我们往右儿子移动;
- 若发现不满足 2 中的两个条件,则停止寻找,当前结点就是最近公共祖先。
时间复杂度
- 每次都会降低一层,故最坏时间复杂度也就是树的高度 $O(h)$。
C++ 代码
/**
* 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 (1) {
if (p -> val < cur -> val && q -> val < cur -> val)
cur = cur -> left;
else if (p -> val > cur -> val && q -> val > cur -> val)
cur = cur -> right;
else
break;
}
return cur;
}
};