day22 公共祖先

当递归函数具有返回值

  1. 搜索一条边
if (递归函数(root->left)) return ;
if (递归函数(root->right)) return ;
  1. 搜索整棵树
left = 递归函数(root->left);
right = 递归函数(root->right);
left与right的逻辑处理;

[235. 二叉搜索树的最近公共祖先](搜索一条边)
二叉搜索树具有有序性
4. cur节点是数值在[p, q]区间中则一定可以说明该节点cur就是q 和 p的公共祖先。
5. cur 大于 q 一定在左子树中
6. cur 大于p 一定在右子树中

class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if(!root || root==p || root ==q) return root;
        if((root->val > p->val && root->val < q->val) || (root->val < p->val && root->val > q->val)) return root;
        if(root-> val > p->val ) return lowestCommonAncestor(root->left, p, q);
        return lowestCommonAncestor(root->right, p, q);
    }
};

236. 二叉树的最近公共祖先(搜索整个树)
思路框架
公共祖先只有两种情况
4. p q 分别在root 两边 那么root就是公共祖先
5. root就是p 或者root就是q 此时root就是公共祖先
6. 当遇到p q 在同一边的时候 递归的去root->left 或者root->right

执行方法一
创建一个find函数判断 能否在这个子树上找到目标

class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if(root == p || root == q) return root;
        if(find(root->left, p) && find(root->left, q)) return lowestCommonAncestor(root->left, p, q);
        else if(find(root->right, p) && find(root->right, q)) return lowestCommonAncestor(root->right, p, q);
        return root;
    }
    bool  find(TreeNode* root, TreeNode* node){
        if(!root) return false;
        if(root == node) return true;
        return find(root->left, node) || find(root->right, node);
    }
};

find函数的功能可以用 lowestCommonAncestor 代替

  1. 返回值 如果遇到p或者q,就把q或者p返回,返回值不为空,就说明找到了q或者p。
  2. 如果left 和 right都不为空,说明此时root就是最近公共节点
  3. 如果left为空,right不为空,就返回right,说明目标节点是通过right返回的。
  4. 如果right为空,left不为空,就返回left
  5. 如果 左右返回都是 null 那么返回null就可以了
class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if(!root || root == p || root == q) return root;
        cout<<root->val<<endl;;
        TreeNode * left = lowestCommonAncestor(root->left, p, q);
        TreeNode * right = lowestCommonAncestor(root->right, p, q);
        
       if(left && right) return root;
       if(left && ! right) return left;
       if(!left && right) return right;
       return NULL;
     
    }
   
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值