剑指offer 76- 树中两个结点的最低公共祖先

2021-06-11  本文已影响0人  顾子豪

给出一个二叉树,输入两个树节点,求它们的最低公共祖先。

一个树节点的祖先节点包括它本身。

注意:

输入的二叉树不为空;
输入的两个节点一定不为空,且是二叉树中的节点;

样例

二叉树[8, 12, 2, null, null, 6, 4, null, null, null, null]如下图所示:
    8
   / \q
  12  2
     / \
    6   4

1. 如果输入的树节点为2和12,则输出的最低公共祖先为树节点8。

2. 如果输入的树节点为2和6,则输出的最低公共祖先为树节点2。

分析:
算法一:递归

若 rootrootroot 是 p,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* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if(!root || root==p || root==q) return root;//递归终止条件
        auto left = lowestCommonAncestor(root->left, p, q);
        auto right = lowestCommonAncestor(root->right, p, q);
        if(left && right) return root;//两个节点分别位于左子树和右子树
        if(!left) return right;//左子树中两个节点都找不到
        return left;//右子树中两个节点都找不到
    }
};

复杂度分析

算法二:存储父节点

我们可以用哈希表存储所有节点的父节点,然后我们就可以利用节点的父节点信息从 p 结点开始不断往上跳,并记录已经访问过的节点,再从 q 节点开始不断往上跳,如果碰到已经访问过的节点,那么这个节点就是我们要找的最近公共祖先。

从根节点开始遍历整棵二叉树,用哈希表记录每个节点的父节点指针。
从 p 节点开始不断往它的祖先移动,并用数据结构记录已经访问过的祖先节点。
同样,我们再从 q 节点开始不断往它的祖先移动,如果有祖先已经被访问过,即意味着这是 p 和 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:
    unordered_map<TreeNode*, TreeNode*> father;
    unordered_map<TreeNode*, bool> vis;
    void dfs(TreeNode* root) {
        if(root->left) father[root->left] = root, dfs(root->left);
        if(root->right) father[root->right] = root, dfs(root->right);
    }
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {   
        father[root] = nullptr;
        dfs(root);
        while(p) vis[p] = true, p = father[p];
        while(q) {
            if(vis[q]) return q;
            q = father[q];
        }
        return nullptr;
    }
};
上一篇下一篇

猜你喜欢

热点阅读