Leetcode 236. 二叉树的最近公共祖先

解法1:

解法1借鉴于力扣官方解法,这里只是记录一下

二叉树的最近公共祖先一共有三种情况:

1. p或者q在左子树

2. p或者q在右子树

3. 根自己就是p或者q,则另一个p或q在左子树中或是右子树中

记左子树为l_{son}, 则右子树为r_{son},上述情况可表达为:

(l_{son} \&\& r_{son}) || ((x =p || x = q)\&\&(l_{son} || r_{son}))

根据上面表达式,可以确定公共祖先。

当左子树包含p或q时,左子树为真,当右子树包含p或q时,右子树为真,根为p或q时,根为真,根据此,可以递归向下找,向下的条件为:

l_{son} || r_{son}|| (x =p || x = q)

可以写出以下代码

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode* ans;
    
    bool dfs(TreeNode* root, p, q)
    {
        if(root == NULL)
            return false;
        bool left = dfs(root->left,p,q);
        bool right = dfs(root->right,p,q);
        if((left&&right)||((root->val == p||root->val == q)&&(left||right))
            ans = root;
        return (left||right||(root->val == p || root-val == q);
    }
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        dfs(root,p,q);   
        return ans;
    }
};

解法二:

通过p和q的路径去找,两种情况

1. 当p和q不在同一路径上,p和q在左子树或是右子树里。

2. 当p和q在同一路径上时,p和q有一个为根节点。

第一种情况,找到p的路径和q的路径,找到二者路径不同前的最后一个相同的节点,即为最近公共祖先。

第二种情况,同样找到二者的路径,p和q最后一个相同的节点即为最近公共祖先。

这里可以借用栈来实现。

解法三:

利用递归的解法。

首先明确基本情况是

1. 当递归到为空时,肯定返回空。

2. 当找到了p或者q时,直接返回这个节点。

可以写出基本的代码,也就是函数的出口。

递归去返回左边和右边的情况,这里用后序遍历的时机,也就是说当子树已经知道自己是什么情况的时候,往上逐层去返回。

分别从左边去递归和从右边去递归,左边要不然找到p或者q,要不然为空,右边也是一样。

每个子树知道了自己的情况后,该怎么向上面汇报呢,或者说汇报什么呢,左右子树又有四种情况:

1. 左右子树都为空,自然返回空;

2. 左右子树都不为空,找到了!返回root;

3. 左边不为空右边为空,返回左边的;

4. 右边不为空左边为空,返回右边的;

最后两种情况可以综合一下,哪边不为空返回哪边的。

所以可以写出如下的代码:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     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) {
        if(root == NULL)
            return root;
        if(root == q || root == p)
            return root;
        TreeNode* ltree = lowestCommonAncestor(root->left, p,q);
        TreeNode* rtree = lowestCommonAncestor(root->right,p,q);
        if(ltree == NULL && rtree == NULL)
            return NULL;
        if(ltree!= NULL && rtree!= NULL)
            return root;
        //if(ltree == NULL || rtree == NULL)
        return ltree == NULL ? rtree : ltree;
    }
};

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值