通知 网站从因情语写改为晴雨,这个网站的模板也从calmlog_ex改为 whimurmur

leetcode 剑指 Offer 68 - II. 二叉树的最近公共祖先

101人浏览 / 0人评论 / | 作者:whisper  | 分类: 剑指offer2  | 标签: 剑指offer2  | 

作者:whisper

链接:https://www.proprogrammar.com/article/846

声明:请尊重原作者的劳动,如需转载请注明出处


剑指 Offer 68 - II. 二叉树的最近公共祖先

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

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

例如,给定如下二叉树:  root = [3,5,1,6,2,0,8,null,null,7,4]

示例 1:

输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
输出: 3
解释: 节点 5 和节点 1 的最近公共祖先是节点 3。

示例 2:

输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4
输出: 5
解释: 节点 5 和节点 4 的最近公共祖先是节点 5。因为根据定义最近公共祖先节点可以为节点本身。

说明:

所有节点的值都是唯一的。
p、q 为不同节点且均存在于给定的二叉树中。
注意:本题与主站 236 题相同:https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree/


本题是:简单题,标签是:树,编程语言是:c++


我的解法

/**
 * 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:
    // c++重写,题解方法
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if(root == NULL)return NULL;        
        if(root == p||root == q)return root;
        TreeNode* left = lowestCommonAncestor(root->left, p, q);
        TreeNode* right = lowestCommonAncestor(root->right, p, q);
        if(left && right)return root;
        return left ? left : right; // 只有一个非空则返回该指针,两个都为空则返回空指针
    }
};

代码很短,讲一下思想:root可能是公共结点,或者公共结点的祖先结点,如果root == p || root == q,那么是公共结点,如果root不是,那么公共祖先在左边或右边,两边找一下,哪边找到了就选哪边的公共结点,找不到时最后就会return NULL


其它解法

/**
 * 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) {
        
        vector<TreeNode*> ppath;
        vector<TreeNode*> qpath;
        vector<TreeNode*> path;
        bool pfound = false;
        bool qfound = false;
        function<void(TreeNode*)> dfs = [&](TreeNode* root) {
            if (!root || pfound && qfound) return;
            path.push_back(root);
            if (root == p) {
                pfound = true;
                ppath = path;
            }
            else if (root == q) {
                qfound = true;
                qpath = path;
            }
            dfs(root->left);
            dfs(root->right);
            path.pop_back();
        };
        dfs(root);
        int i = 0;
        while (i < ppath.size() && i < qpath.size() && ppath[i] == qpath[i]) i++;
        return ppath[i - 1];
    }
};

做法:这里是先找到从根结点到p, q的路径(dfs),然后找到最后一个重复路径的结点(ppath[i-1]),就是最近公共祖先


亲爱的读者:有时间可以点赞评论一下

点赞(2) 打赏

全部评论

还没有评论!
广告位-帮帮忙点下广告