力扣-找公共祖先问题

力扣-找公共祖先问题

方法1:看是不是在节点的左右节点,如果在,就说明root即使节点

class Solution {
public:
    bool Find(TreeNode* root, TreeNode*x)//找节点
    {
     if(root==nullptr)
        return false;
     if(root==x)
        return true;
     return Find(root->left,x)||Find(root->right,x);
    }
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) 
    {
        if(root==nullptr)
            return nullptr;
        if(root==p||root==q)
            return root;
        bool IspLeft,IspRight,IsqLeft,IsqRight;//定义bool变量,看是不是在左右边
        IspLeft=Find(root->left,p);//看p是不是在左边
        IspRight=!IspLeft;//是不是在右边
        IsqLeft=Find(root->left,q);
        IsqRight=!IsqLeft;

        if((IspLeft&&IsqRight)||(IspRight&&IsqLeft))//两个节点一个在左边,一个在右边,及root就是要找的公共节点
        {
            return root;
        }
        else if(IspLeft&&IsqLeft)//如果都在左边,就不用往右边找了
            return lowestCommonAncestor(root->left,p,q);
        else if(IspRight&&IsqRight)//如果都在右边,就只找右边就行
            return lowestCommonAncestor(root->right,p,q);
        else
            return nullptr;
    }
};

方法2:保存路径


class Solution {
public:
    bool pPath(TreeNode* root, TreeNode*x,stack<TreeNode*>& st)
    {
        if(root==nullptr)
            return false;
        st.push(root);
        if(root==x)
            return true;
      
        if(pPath(root->left,x,st))
        {
            return true;
        }
        if(pPath(root->right,x,st))
        {
            return true;
        }
        st.pop();
        return false;
    }
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) 
    {
        stack<TreeNode*> stp,stq;
        pPath(root,p,stp);
        pPath(root,q,stq);

        int szp=stp.size();
        int szq=stq.size();
        while(szp!=szq)
        {
            if(szp>szq)
            {
                szp--;
                stp.pop();
            }
            else
            {
                szq--;
                stq.pop();
            }
               
        }
        while(stp.top()!=stq.top())
        {
            stp.pop();
            stq.pop();
        }
        return stp.top();
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值