lettcode.236二叉树的最近公共祖先
解法一
我们找规律后会发现, 节点p和节点q分别在公共节点的左右子树中,因此我们可以分三种情况讨论:
- 当p、q节点都在
root
的左子树中时,那就递归到root->left
中找 - 当p、q节点都在
root
的右子树中时,那就递归到root->right
中找 - 当p、q节点在
root
的左、右子树中或者root等于p、q中的一个节点时,就返回root
bool isIntree(TreeNode* root,TreeNode* x)
{
if(root == nullptr)
return false;
if(x == root)
return true;
return isIntree(root->left,x) || isIntree(root->right,x);
}
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if(root == p || root == q)
return root;
bool pInleft = isIntree(root->left,p);
bool pInright = !pInleft;
bool qInleft = isIntree(root->left,q);
bool qInright = !qInleft;
if(pInleft&&qInright ||qInleft&&pInright)
return root;
if(pInleft && qInleft)
return lowestCommonAncestor(root->left,p,q);
if(pInright && qInright)
return lowestCommonAncestor(root->right,p,q);
return nullptr;
}
解法二
我们可以使用两个stack
分别来记录从根节点到p、q节点的路径,记为pPath
和qPath
当两条路径长度不同时,使较长路径不断pop
,然后两条路径同时pop
,直到pPath.top() == qPath.top()
bool findPath(stack<TreeNode*>& path,TreeNode* x,TreeNode* root)
{
if(root == nullptr)
return false;
path.push(root);
if(root == x)
return true;
if(findPath(path,x,root->left))
return true;
… pPath.pop();
qPath.pop();
}
return pPath.top();
}