235.二叉搜索树的最近公共祖先
标签: tree
, binary-search-tree
, depth-first-search
难度: Medium
通过率: 66.79%
原题链接: https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-search-tree/description/
题目描述
给定一个二叉搜索树(BST),找到其中两个给定节点的最近公共祖先(LCA)。根据维基百科中的定义:“两个节点 p 和 q 的最近公共祖先是能够同时通过子树拥有 p 和 q 作为后代的最低节点(我们允许一个节点是它自己的后代)。”
解题思路
在二叉搜索树中,通过性质:左子树所有节点的值小于根节点值,右子树所有节点的值大于根节点值。我们可以从根节点出发,比较当前节点与 p 和 q 的值关系。如果当前节点的值大于 p 和 q 的值,说明它在公共祖先的右边,我们需要往左子树继续找;反之,如果当前节点的值小于 p 和 q 的值,说明它在公共祖先的左边,我们需要往右子树继续找;当当前节点的值介于 p 和 q 之间时,或者当前节点等于其中之一,则说明当前节点是公共祖先。
代码实现
- Python
- C++
- JavaScript
- Java
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
def lowestCommonAncestor(root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
# 遍历树,寻找LCA
current = root
while current:
# 如果当前节点的值大于p和q的值,往左走
if p.val < current.val and q.val < current.val:
current = current.left
# 如果当前节点的值小于p和q的值,往右走
elif p.val > current.val and q.val > current.val:
current = current.right
else:
# 找到LCA
return current
class TreeNode {
public:
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* current = root;
// 遍历直到找到LCA
while (current) {
if (p->val < current->val && q->val < current->val)
current = current->left;
else if (p->val > current->val && q->val > current->val)
current = current->right;
else
return current;
}
return nullptr;
}
};
function TreeNode(val, left, right) {
this.val = (val===undefined ? 0 : val)
this.left = (left===undefined ? null : left)
this.right = (right===undefined ? null : right)
}
var lowestCommonAncestor = function(root, p, q) {
let current = root;
while (current) {
if (p.val < current.val && q.val < current.val) {
current = current.left;
} else if (p.val > current.val && q.val > current.val) {
current = current.right;
} else {
return current;
}
}
};
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
}
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
TreeNode current = root;
while (current != null) {
if (p.val < current.val && q.val < current.val)
current = current.left;
else if (p.val > current.val && q.val > current.val)
current = current.right;
else
return current;
}
return null;
}
}
复杂度分析
时间复杂度为 ,其中 是二叉搜索树的高度。在最坏情况下,这个复杂度可能为 ,其中 是节点的数量(例如,当没有平衡的树时)。
空间复杂度为 ,因为我们使用了迭代而不是递归,没有额外的递归调用栈开销。