Lowest Common Ancestor of a Binary Tree(最小公共祖先)

  1. Lowest Common Ancestor of a Binary Tree

Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree.

According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes p and q as the lowest node in T that has both p and q as descendants (where we allow a node to be a descendant of itself).”

Given the following binary tree: root = [3,5,1,6,2,0,8,null,null,7,4]

Example 1:

Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
Output: 3
Explanation: The LCA of nodes 5 and 1 is 3.
Example 2:

Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4
Output: 5
Explanation: The LCA of nodes 5 and 4 is 5, since a node can be a descendant of itself according to the LCA definition.

Note:

All of the nodes’ values will be unique.
p and q are different and both values will exist in the binary tree.

题意: 就是找出两个节点(p,q)的最近公共祖先。

首先思路:
1: 如果存在某一个节点(root),p存在于root的左子树,而q存在于root的右子树,那么root必然是p,q节点的最近公共祖先。
2: 如果p,q节点存在于root的左子树或者右子树,那么可以继续递归下去。

代码:

class Solution
{
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q)
    {
        // 如果都在左子树,那么继续递归下去
        if(hasNode(root->left, p) && hasNode(root->left, q))
            return lowestCommonAncestor(root->left, p, q);
        if(hasNode(root->right, p) && hasNode(root->right, q))
            return lowestCommonAncestor(root->right, p, q);
        return root;
    }
    bool hasNode(TreeNode*root, TreeNode* p)
    {
        if(root == nullptr) return false;
        if(root == p) return true;
        return hasNode(root->left, p) || hasNode(root->right, p);
    }
};

这种方法是二叉树的每个节点都要进行遍历,所以时间复杂度为O(n^2).但是也是最容器理解的。

方法2 :也是同样的原理,但是自底向上的。也是同样的原理,如果左右节点都存在,那么必然这个root是最小公共祖先。

代码:

class Solution
{
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q)
    {
        if(root == nullptr) return nullptr;
        if(root == p || root ==q) return root;
        TreeNode* L = lowestCommonAncestor(root->left, p, q);
        TreeNode* R = lowestCommonAncestor(root->right, p ,q);
        if (L) cout << L->val << endl;
        if(L && R) return root;
        return L?L:R;
    }
};

方法3:针对p,q直接找到其路径,然后找到最后一个相同的点即可,求的就是最近公共祖先。

class Solution
{
public:

    void print(vector tmp)
    {
        for(int i = 0; i < tmp.size(); i++)
        {
            if(i == tmp.size()-1) cout << tmp[i]->val << endl;
            else cout << tmp[i]->val << " ";
        }
    }

    void findpath(TreeNode* root, TreeNode* p, vectortmp_path, vectorans, bool &ok)
    {
        if(root == nullptr) return;
        if(ok) return;
        tmp_path.push_back(root);
        if(root == p)
        {
            ok = true;
            for(int i = 0; i < tmp_path.size(); i++)  ans.push_back(tmp_path[i]);
            return;
        }
        findpath(root->left, p, tmp_path, ans, ok);
        findpath(root->right, p, tmp_path, ans, ok);
        tmp_path.pop_back();
    }

    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q)
    {
        vector path_p, path_q;
        vector tmp_path;
        TreeNode* parent;
        bool ok = false;
        findpath(root, p, tmp_path, path_p, ok);
       // print(path_p);
        ok = false;
        tmp_path.clear();
        findpath(root, q, tmp_path, path_q, ok);
       // print(path_q);
        for(int i = 0; i < path_p.size(); i++)
        {
            ok = false;
            for(int j = 0; j < path_q.size(); j++)
            {
                if(path_p[i] == path_q[j])
                {
                    ok = true;
                    break;
                }
            }
            if(!ok)
            {
                parent = path_p[i-1];
                break;
            }
        }
        if(ok) return path_p[path_p.size()-1];
        return parent;
    }
};

int main()
{
    TreeNode* p1 = new TreeNode(1);
    TreeNode* p2 = new TreeNode(2);
    TreeNode* p3 = new TreeNode(3);
    TreeNode* p4 = new TreeNode(4);
    TreeNode* p5 = new TreeNode(5);
    TreeNode* p6 = new TreeNode(6);
    TreeNode* p7 = new TreeNode(7);
    TreeNode* p8 = new TreeNode(8);

    p1->left = p2;
    p1->right = p3;
    p2->left = p4;
    p2->right = p5;
    p3->left = p6;
    p3->right = p7;
    p4->left = p8;

    Solution so;
    cout << so.lowestCommonAncestor(p1, p4, p8)->val << endl;


    return 0;
}

你可能感兴趣的:(bestcoder,Leetcode)