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).”
解法一,利用递归方法
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if (!root || root == p || root == q)
return root;
//对于每一节点,如果left 和right其中一个没找到的话,说明该节点不是lca,需要向上传递该非空值。终于搞明白了啊。
TreeNode* left = lowestCommonAncestor(root->left, p, q);//左支找root ==p的。
TreeNode* right = lowestCommonAncestor(root->right, p, q);
//return !left ? right : !right ? left : root;
if (left && right) return root;
return left ? left : right;
}
};
解法二 利用节点路径找最后的公共节点就行。
//找到给定点的路径,最低公共节点就是分叉的节点。
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode*p, TreeNode* q) {
if (root == nullptr || p == nullptr || q == nullptr);
vector<TreeNode*> pathp;
vector<TreeNode*> pathq;
pathp.push_back(root);
pathq.push_back(root);
getPath(root, p, pathp);
getPath(root, q, pathq);
TreeNode* lca = nullptr;
for (int i = 0; i < pathp.size() && i < pathq.size(); i++) {
if (pathp[i] == pathq[i])
lca = pathp[i];
else
break;
}
return lca;
}
private:
bool getPath(TreeNode* root, TreeNode* n, vector<TreeNode*>& path) {
if (root == n)
return true;
if (root->left != nullptr) {
path.push_back(root->left);
if (getPath(root->left, n, path))
return true;
path.pop_back();
}
if (root->right != nullptr) {
path.push_back(root->right);
if (getPath(root->right, n, path))
return true;
path.pop();
}
return false;
}
};
解法三
//看不懂呀什么算法
class Solution {
struct Frame {
TreeNode* node;
Frame* parent;
vector<TreeNode*> subs;
};
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
Frame answer;
stack<Frame> stack;
stack.push({ root, &answer });
while (stack.size()) {
Frame *top = &stack.top();
Frame* parent = top->parent;
TreeNode* node = top->node;
if (!node || node == p || node == q) {
parent->subs.push_back(node);
stack.pop();
}
else if (top->subs.empty()) {
stack.push({ node->right, top });
stack.push({ node->left, top });
}
else {
TreeNode* left = top->subs[0];
TreeNode* right = top->subs[1];
parent->subs.push_back(!left ? right : !right ? left : node);
stack.pop();
}
}
return answer.subs[0];
}
};