leetcode235
问题描述:给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
示例:
思路:题目中给出的是一棵「二叉搜索树」,因此我们可以快速地找出树中的某个节点以及从根节点到该节点的路径,例如我们需要找到节点 p:
我们从根节点开始遍历;如果当前节点就是 p,那么成功地找到了节点;如果当前节点的值大于 p 的值,说明 p 应该在当前节点的左子树,因此之后遍历当前子树的左子树;如果当前节点的值小于p 的值,说明 p 应该在当前节点的右子树,因此之后遍历当前子树的右子树。
当我们用上述方法得到了从根节点到 p 和 q的路径之后,我们只需要从头到尾遍历他们的路径,最后一个相同的值即为它们的分岔点。
方法:
//查找二叉搜索树到任意结点的路径
vector<TreeNode *>getPath(TreeNode *root,TreeNode *target){
vector<TreeNode *>path; //存储路径
TreeNode *node=root;
while(node!=target){
path.emplace_back(node);
if(node->val>target->val){
//在左子树进行查找
node=node->left;
}else{
//在右子树进行查找
node=node->right;
}
}
//存储target结点
path.emplace_back(node);
return path;
}
//查找二叉搜索树两个结点的最近公共祖先
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q){
//查找从根节点到p结点的路径
auto p_path=getPath(root,p);
//查找从根节点到q结点的路径
auto q_path=getPath(root,q);
//两个路径的最后一个相同的结点即为最近公共结点
int lowest_node_position=0;
for(int i=0,j=0;i<p_path.size()&&j<q_path.size();++i,++j){
if(p_path[i]==q_path[j]){
lowest_node_position=i;
}else
break;
}
return p_path[lowest_node_position];
}