leetcode hot 100之:二叉树的最近公共祖先

发布于:2025-06-25 ⋅ 阅读:(18) ⋅ 点赞:(0)

本来不打算写的哈哈哈但是发现这一道递归我是有思路的!!自己能想到一些方向!我真棒!所以记录一下哈哈哈

我的思路:

1、祖先一定是自身或往上找,所以如何逆着走呢?

2、3种情况:

有一个结点是另一个结点父节点 ,那么返回其中一个结点本身;

这两个结点是兄弟结点,那么返回他们的父亲结点;(回到上一个问题,怎么找父节点?);

不是父子也不是兄弟,那么就继续往上找。

方法一:递归

看了题解发现,我想的3种情况中,2和3可以合并,也就是往上找的情况。看这个题解是否能明白呢?

因为树的遍历是从上往下,所以方便地递归判断其左右子树,因此解题方法需要立足于从上往下,这和我的思路的不同的。 

 代码:

TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if(!root)
        return NULL;
        if(root==p||q==root)
        return root;
        TreeNode* leftnode=lowestCommonAncestor(root->left,p,q);
        TreeNode* rightnode=lowestCommonAncestor(root->right,p,q);
        if(rightnode&&leftnode)return root;
        if(leftnode)return leftnode;
        if(rightnode)return rightnode;
        //如何判断left或right就是最近的点呢?
        return NULL;
    }

和官方题解的不太一样哈哈哈,我个人比较习惯这种写法

方法二:

真的可以存储父节点欸!用dfs遍历! 是个很奇妙的思路!

代码:

class Solution {
public:
    unordered_map<int,TreeNode*>fa;//存储父节点
    unordered_map<int,bool>vis;//一个结点的父节点是否是另一个结点的父节点
     void dfs(TreeNode* root)
     {
        if(root->left)
        {
            fa[root->left->val]=root;
            dfs(root->left);
        }//把左子树都记录下父节点
        if(root->right)
        {
            fa[root->right->val]=root;
            dfs(root->right);
        }
     }
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if(!root)
        return NULL;
        dfs(root);//遍历,记录哈希表
        while(p!=NULL)
        {
            vis[p->val]=true;
            p=fa[p->val];
        }//遍历p的所有父节点
        while(q!=NULL)
        {
            if(vis[q->val])
            return q;
            q=fa[q->val];
        }
        return NULL;
    }
};

递归加油!!!!再坚持一下!!!