题目:
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
示例 1:
输入:root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
输出:3
解释:节点 5 和节点 1 的最近公共祖先是节点 3 。
示例 2:
输入:root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4
输出:5
解释:节点 5 和节点 4 的最近公共祖先是节点 5 。因为根据定义最近公共祖先节点可以为节点本身。
提示:
树中节点数目在范围 [2, 105] 内。
-109 <= Node.val <= 109
所有 Node.val 互不相同 。
p != q
p 和 q 均存在于给定的二叉树中。
求解过程:
首先通过队列queue遍历一遍二叉树,在遍历过程中将每个子节点的父节点通过map存储起来。然后用一个map容器temp存储两个目标子节点,每次遍历目标子节点的父节点(可以通过最开始创建的map容器找到),并查看是否在temp中存在,若存在则说明该节点就是两个目标子节点的最近公共祖先节点,若不存在,将父节点存入temp容器中,将该父节点作为下一次循环的子节点继续寻找。
代码实现:
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
queue<TreeNode*> que;
que.push(root);
map<TreeNode*,TreeNode*> mp;//key为子节点,vlaue为父节点
TreeNode* result;
while(!que.empty()){//遍历二叉树,将每个节点的父节点存入到mp中
TreeNode* node=que.front();
que.pop();
if(node->left){
que.push(node->left);
mp[node->left]=node;
}
if(node->right){
que.push(node->right);
mp[node->right]=node;
}
}
map<TreeNode*,int> temp;//用于记录两个目标子节点往上遍历的父节点
temp[p]=1;//将目标子节点存入temp中防止目标子节点就是另一个目标子节点的父节点
temp[q]=1;
TreeNode* t1=p;
TreeNode* t2=q;
while((mp.find(t1)!=mp.end())||(mp.find(t2)!=mp.end())){//以两个目标子节点往上遍历父节点,直到找到最近公共祖先
TreeNode* t3=mp[t1];//记录父节点
TreeNode* t4=mp[t2];
if(t3!=NULL){//要提前判断父节点是否为空,防止错误记录
if(temp.find(t3)!=temp.end()){//查看往上遍历过程中是否已经存储过该节点,存储过者说明该节点就是最近公共祖先
result=t3;
break;
}
else{//如不是更新子节点,将其父节点作为子节点往上遍历
temp[t3]=1;
t1=t3;
}
}
if(t4!=NULL){
if(temp.find(t4)!=temp.end()){
result=t4;
break;
}
else{
temp[t4]=1;
t2=t4;
}
}
}
return result;
}
};
标签:node,TreeNode,temp,祖先,二叉树,236,节点,mp
From: https://blog.csdn.net/2401_84164461/article/details/144200159