题目出处:https://leetcode-cn.com/problems/er-cha-shu-de-zui-jin-gong-gong-zu-xian-lcof/
思路1:定义递归函数findAns(TreeNode* node, TreeNode* p, TreeNode* q),其意义为若以node为根的二叉树中包含节点p或者节点q,则返回true;若以node为根的二叉树中既不包含p也不包含q,则返回false。
解答1:
/**
* 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 {
private:
TreeNode* ans;
public:
bool findAns(TreeNode* node, TreeNode* p, TreeNode* q){ //以node为根的树包含p或q
if(!node){
return false;
}
bool lson = findAns(node->left, p, q);
bool rson = findAns(node->right, p, q);
if((lson && rson) || ((lson || rson) && (node == q || node == p))){
ans = node;
}
return (lson || rson) || (node == q || node == p);
}
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
findAns(root, p, q);
return ans;
}
};
思路2:用哈希表记录每个节点的父节点,先从p节点开始不断向上寻找父节点直到遍历到根节点,并将其均标记为已访问过。在从q节点开始不断向上寻找父节点,当遇到第一个被标记的已访问节点时,就找到p和q的最近公共祖先。
解答2:
/**
* 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 {
private:
unordered_map<TreeNode*, bool> vis;
unordered_map<TreeNode*, TreeNode*> mp;
public:
void find_parent(TreeNode* node){
if(node->left){
mp[node->left] = node;
find_parent(node->left);
}
if(node->right){
mp[node->right] = node;
find_parent(node->right);
}
}
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
mp[root] = nullptr; //保证后面的循环能遍历到根节点
find_parent(root);
while(p){
vis[p] = true;
p = mp[p];
}
while(q){
if(vis[q]){
return q;
}
q = mp[q];
}
return nullptr;
}
};