递归函数:判断当前节点是否包含p节点或q节点。(返回bool)
利用递归函数判断左分支是否包含p/q — ifLeft
,右分支是否包含p/q — ifRight
。
利用条件判断当前节点是否为p/q — ifCurrent
。
递归函数的返回值,由定义(是否包含p、q)得 ifLeft || ifRight || ifCurrent
判断当前节点是否为公共祖先有两种情况:
- 左右子分支分别包含p、q。
ifLeft && ifRight
- 当前节点为p、q中的一个,并且子分支包含另一个。
ifCurrent && (ifLeft || ifRight)
以上两种情况满足任意一个,则为公共祖先。
由于递归函数是自底向上返回,可以保证为最近的公共祖先。
公共祖先需要保证计算的三个值中两个为 True
,经过公共祖先后,条件不再满足,因此可以保证唯一性。
附上代码:
/**
* 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* parent = nullptr;
public:
bool ifContain(TreeNode* node, TreeNode* p, TreeNode* q) {
if(!node) return false;
bool ifLeft = ifContain(node->left, p, q);
bool ifRight = ifContain(node->right, p, q);
bool ifcurrent = (p == node) || (q == node);
if((ifLeft && ifRight) || (ifcurrent && (ifLeft || ifRight))) parent = node;
return ifLeft || ifRight || ifcurrent;
}
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
ifContain(root, p, q);
if(!parent) return root;
return parent;
}
};