力扣236.二叉树最近的公共祖先(内含两种解法

力扣236.二叉树最近的公共祖先(内含两种解法_第1张图片

题目名称 力扣236.二叉树最近的公共祖先

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台


目录

题目名称 力扣236.二叉树最近的公共祖先

1.题目

2.题目分析

3.题目答案

最后


1.题目

给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。

百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

力扣236.二叉树最近的公共祖先(内含两种解法_第2张图片力扣236.二叉树最近的公共祖先(内含两种解法_第3张图片


2.题目分析

解法1

通过观察规律可得,如果一个节点在这个节点的左子树,另一个节点在这个节点的右子树,那么这个节点就是这两个节点的最近公共祖先。

通过Find判断这个节点在当前节点的左子树还是右子树,得到结果后进行判断。如果同时在其左子树或者右子树就进行递归转化,如果一个在左子树一个在右子树就直接返回。

解法2

可以把寻找二叉树节点最近公共祖先的问题转化为链表相交问题。只要找出这两个节点距离根节点的路径,然后再把这两个路径进行比较,后找出两个路径的第一个相同节点,就可以返回了。

这个寻找路径算法是重点,注意传参时stack传引用。如果这个节点对应的左右子树都没有符合条件的节点,那么就要将这个节点pop出队列,如果找到了就return true.


3.题目答案

解法1 找规律

class Solution {
    bool Find(TreeNode* root, TreeNode* p)
    {
        if (root == nullptr)
        {
            return false;
        }

        return (root == p) || (Find(root->left, p)) || (Find(root->right, p));

    }
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {

        if (root == nullptr)
        {
            return nullptr;
        }
        if (root == p || root == q)
        {
            return root;
        }
        bool pInleft = Find(root->left, p);
        bool pInright = !pInleft;
        bool qInleft = Find(root->left, q);
        bool qInright = !qInleft;

        if ((pInleft && qInright) || (pInright && qInleft))
        {
            return root;
        }
        if (pInleft && qInleft)
        {
            return lowestCommonAncestor(root->left, p, q);
        }
        else
        {
            return lowestCommonAncestor(root->right, p, q);
        }
    }
}

解法2 转化为链表相交问题

class Solution {

    bool Find(TreeNode* root, TreeNode* q, stack& st)
    {
        if (root == nullptr)
        {
            return false;
        }
        if (root == q)
        {
            st.push(root);
            return true;
        }
        st.push(root);
        if ((Find(root->right, q, st) == false) && (Find(root->left, q, st) == false))
        {
            st.pop();
            return false;
        }
        else {
            return true;
        }

    }

public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {

        //求路径
        stack stp;
        Find(root, p, stp);

        stack stq;
        Find(root, q, stq);

        //求相交节点
        while (stp.size() > stq.size())
        {
            stp.pop();
        }
        while (stp.size() < stq.size())
        {
            stq.pop();
        }
        while (stp.top() != stq.top())
        {
            stq.pop();
            stp.pop();
        }
        return stp.top();


    }
};

最后

除夕快乐!!

力扣236.二叉树最近的公共祖先(内含两种解法_第4张图片

你可能感兴趣的:(题目分享:一些容易遗忘的小点,leetcode,算法,数据结构)