剑指 Offer 68 - I. 二叉搜索树的最近公共祖先
难度:简单。
根据二叉搜索树的性质来找答案,如果当前节点大于p,q中的较小值,小于p,q中的较大值,则p,q位于当前节点的左右子树,当前节点为需要寻找的节点。其他情况也根绝二叉搜索树性质进行判断,具体见代码。
正确解法:
/**
* 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 {
TreeNode* getNode(TreeNode* root, int min_val, int max_val){
if(root->val == min_val || root->val == max_val)return root;
if(root->val > min_val && root->val < max_val)return root;
if(root->val > max_val){
return getNode(root->left, min_val, max_val);
}
if(root->val < min_val){
return getNode(root->right, min_val, max_val);
}
return NULL;
}
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
int min_val = p->val;
int max_val = q->val;
if(min_val > max_val)swap(min_val, max_val);
return getNode(root, min_val, max_val);
}
};
结果:
剑指 Offer 68 - II. 二叉树的最近公共祖先
难度:简单。
使用一个结构体存储has_p, has_q,分别表示某节点的子树是否包含p和q。
正确解法:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
struct Ans{
bool has_p, has_q;
Ans(bool hasP, bool hasQ):has_p(hasP), has_q(hasQ){}
};
class Solution {
TreeNode* ans = nullptr;
Ans getNode(TreeNode* root, TreeNode* p, TreeNode* q){
if(ans != nullptr)return Ans(true, true);
if(root == nullptr){
return Ans(false, false);
}
Ans left_ans = getNode(root->left, p, q);
Ans right_ans = getNode(root->right, p, q);
bool hasP = left_ans.has_p || right_ans.has_p, hasQ = left_ans.has_q || right_ans.has_q;
if(root->val == p->val)hasP = true;
else if(root->val == q->val)hasQ = true;
if(hasP && hasQ && ans == nullptr){
ans = root;
}
return Ans(hasP, hasQ);
}
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
getNode(root, p, q);
return ans;
}
};
结果:
可以不使用结构体,只用一个bool来表示每个节点的子树是否包含p或者q,包含其中一个则为true。因为树中的节点是唯一的,因此如果某一节点的左子树和右子树都为true,则肯定是一个包含p,另一个包含q。则该节点一定是p和q的公共祖先。
利用这个思想,可以不适用结构体。
正确解法:
/**
* 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 {
TreeNode* ans = nullptr;
bool getNode(TreeNode* root, TreeNode* p, TreeNode* q){
if(ans != nullptr)return true;
if(root == nullptr)return false;
bool left_ans = getNode(root->left, p, q);
bool right_ans = getNode(root->right, p, q);
if(ans == nullptr){
if((left_ans && right_ans) ||
((left_ans || right_ans) && (root->val == p->val || root->val == q->val))){
ans = root;
}
}
return (left_ans || right_ans || root->val == p->val || root->val == q->val);
}
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
getNode(root, p, q);
return ans;
}
};
结果: