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;
}
};