Lowest Common Ancestor of a Binary Search Tree (BST)

Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BST.

According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes v and w as the lowest node in T that has both v and w as descendants (where we allow a node to be a descendant of itself).”

        _______6______
       /              \
    ___2__          ___8__
   /      \        /      \
   0      _4       7       9
         /  \
         3   5

For example, the lowest common ancestor (LCA) of nodes 2 and 8 is 6. Another example is LCA of nodes 2 and 4 is 2, since a node can be a descendant of itself according to the LCA definition.


思路,先判断入口是否有非法输入。

1 如果某一个root==p || root == q,那么LCA肯定是root(因为是top down,LCA肯定在root所囊括的树上,而root又是p q其中一个节点了,那么另外一个节点肯定在root之下,那么root就是LCA),那么返回root

2 如果root<min(p, q),那么LCA肯定在右子树上,那么递归

3 如果max(p, q)<root,那么LCA肯定在左子树上,那么递归

4 如果p<root<q,那么root肯定为LCA

以下代码仅为自己记录。

复制代码
#include <iostream>
using namespace std;

typedef struct{
    int value;
    Node *pLeft;
    Node *pRight;
}Node;

Node* LCA(Node *root, Node *p, Node *q)
{
    if (!root || !p || !q)            // 注意还要判断p和q是否为NULL
        return NULL;

    if (root->value == p->value || root->value == q->value)    //这一行可以调整到最后,和最后一个return root(注释a)合并起来 //下次在整理思路的时候,就可以考虑把这两个合并
        return root;

    if (root->value < p->value && root->value < q->value)
        return LCA(root->pRight, p, q);

    if (root->value > p->value && root->value > q->value)
        return LCA(root->pLeft, p, q);

    return root;        //a
}

int main()
{
    
}
复制代码

然后发现有2个逻辑分支可以合并,就是1 4,都是返回root,所以可以把1 4合并,这里直接给出官方solution,自己就不再optimize了:

复制代码
Node *LCA(Node *root, Node *p, Node *q) {
  if (!root || !p || !q) return NULL;
  if (max(p->data, q->data) < root->data)
    return LCA(root->left, p, q);
  else if (min(p->data, q->data) > root->data)
    return LCA(root->right, p, q);
  else
    return root;
}
复制代码

除此之外,还要跟面试官confirm p q是否一定是root下层的某个孩子,如果不一定是,那么需要自己写个Check函数

复制代码
bool Check(Node *root, Node *pNode)
{
    if (!root || !pNode)
        return NULL;

    while (root->value != pNode->value)        // 这里一定要用一个pTemp来指向root来进行遍历,因为你改变了root,就给调用者造成了麻烦!
    {
        if (!root)                            // 这个可以合并到while()的判断条件中去    使得这个循环有2种情况下退出:1 pTemp和pNode的value相等 2 root已经是叶子节点的子节点了,那就不用再往下走了
            break;
        if (root->value > pNode->value)
            root = root->pLeft;
        else if (root->value < pNode->value)
            root = root->pRight;
    }

    if (!root)
        return false;
    else if (root->value == pNode->value)
        return true;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值