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