Lowest Common Ancestor of a Binary Tree -- leetcode

来源:互联网 发布:高德地图大数据发现 编辑:程序博客网 时间:2024/06/05 02:12

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 v and w as the lowest node in T that has both v and w as descendants (where we allow a node to be a descendant of itself).”

        _______3______       /              \    ___5__          ___1__   /      \        /      \   6      _2       0       8         /  \         7   4

For example, the lowest common ancestor (LCA) of nodes 5 and 1 is 3. Another example is LCA of nodes 5 and 4 is 5, since a node can be a descendant of itself according to the LCA definition.



算法一:递归

1. 先在左子树找LCA;再在右子树找LCA。 返回过程中,如果没有找到LCA,找到p, 或者q,也将其返回。

2. 如果左右子树,返回值都不为空,则本节点为LCA。  说明p,q 分别在左,右子树,或者相反。


要注意的事,此题有个陷阱,比较节点,要比较指针值,而不能比较指指向的val字段。比如不能 root->val == p-val , 而要 root == p。

因为测试用例中,有大量重复的val。也就意味着LCA不唯一了。


/** * 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;        else            return left ? left : right;    }};


算法二,先序遍历

在进行先序遍历中,

1.访问本结点和左子树,右子树后,发现p, q值已经找到,则本节点就是LCA


class Solution {public:    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {        bool flagp = false, flagq = false;        return dfs(root, p, q, flagp, flagq);    }        TreeNode* dfs(TreeNode* root, TreeNode* p, TreeNode* q, bool& flagp, bool& flagq) {        if (!root)            return root;                    auto flagp_ = flagp;        auto flagq_ = flagq;        flagp = root == p ? !flagp : flagp;        flagq = root == q ? !flagq : flagq;        auto left = dfs(root->left, p, q, flagp, flagq);        auto right = dfs(root->right, p, q, flagp, flagq);        if (left || right)            return left ? left : right;        if (flagp_ != flagp && flagq_ != flagq)            return root;        return NULL;    }};


也可以稍作改进一下,如果访问本节点和左子树已经找到LCA时,不再访问右子树了。如下:

class Solution {public:    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {        bool flagp = false, flagq = false;        return dfs(root, p, q, flagp, flagq);    }        TreeNode* dfs(TreeNode* root, TreeNode* p, TreeNode* q, bool& flagp, bool& flagq) {        if (!root)            return root;                    auto flagp_ = flagp;        auto flagq_ = flagq;        flagp = root == p ? !flagp : flagp;        flagq = root == q ? !flagq : flagq;        auto ans = dfs(root->left, p, q, flagp, flagq);        if (ans)            return ans;        if (flagp_ != flagp && flagq_ != flagq)            return root;                    ans = dfs(root->right, p, q, flagp, flagq);        if (ans)            return ans;        if (flagp_ != flagp && flagq_ != flagq)            return root;        return NULL;    }};


0 0
原创粉丝点击