二叉树的最近公共祖先--递归--回溯

 思路:

                如果能够自底向上查找元素,就能找到公共祖先了

                 回溯啊:回溯就是天然的自底向上查找元素。

                而后序遍历就是天然的回溯过程:因为后序遍历先处理的一定是叶子节点,

接下来就是逻辑处理过程,

1,如果一个节点的左为p(q),右为q(p),那这个节点一定是最近的祖先。

2,如果走到左树的节点(p)为null,而右树(q)找到节点,此时,祖先(q)一定为右节点,p在q的左右子树里面,q为最近祖先

3,如果两个节点都为空,说明没有公共祖先

递归三部曲:

 

1,确定递归函数返回值以及参数

        需要递归函数告诉我们,是否找到了这个节点,但我们最后要返回节点,所以需要返回找到的当前节点,如果返回值为null,说明没找到

TreeNode*left=lowestCommonAncestor(root->left,p,q);

2,确定终止条件

如果找到了节点p或者q或者走到nullptr,直接返回

if(root==p||root==q||root==nullptr)return root

3,确定递归单层逻辑

值得注意的是 本题函数有返回值,是因为回溯的过程需要递归函数的返回值做判断,但本题我们依然要遍历树的所有节点。

递归函数有返回值就是要遍历某一条边,但有返回值也要看如何处理返回值!

搜索一条边的写法

if(递归函数(root->left))return ;
if(递归函数(root->right))return ;

搜索一颗树的写法

left = 递归函数(root->left);
right = 递归函数(root->right);
left与right的逻辑处理;

在递归函数有返回值的情况下:如果要搜索一条边,递归函数返回值不为空的时候,立刻返回,如果搜索整个树,直接用一个变量left、right接住返回值,这个left、right后序还有逻辑处理的需要,也就是后序遍历中处理中间节点的逻辑(也是回溯)。

逻辑处理:

 //处理逻辑
        if(left!=nullptr&&right!=nullptr)return root;
        if(left==nullptr&&right!=nullptr)
        return right;
        else if(left!=nullptr&&right==nullptr)
        return left;
        else return nullptr;

代码:

class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) 
    {
        if(root==p||root==q||root==nullptr)return root;
        //递归查找左右节点
        TreeNode*left=lowestCommonAncestor(root->left,p,q);
        TreeNode*right=lowestCommonAncestor(root->right,p,q);
        //处理逻辑
        if(left!=nullptr&&right!=nullptr)return root;
        if(left==nullptr&&right!=nullptr)
        return right;
        else if(left!=nullptr&&right==nullptr)
        return left;
        else return nullptr;
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

想找后端开发的小杜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值