定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 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 。
因为根据定义最近公共祖先节点可以为节点本身。
示例 3:
输入:root = [1,2], p = 1, q = 2 输出:1
提示:
- 树中节点数目在范围
[2, 105]
内。 -109 <= Node.val <= 109
- 所有
Node.val
互不相同
。 p != q
p
和q
均存在于给定的二叉树中。
题解:(离根节点越近,高度越高),将p,q看作指针
两个节点的最近公共祖先所在的高度一定大于等于 两个节点中最高的那个节点p,因此将高度较矮的节点q沿着他的父节点向上爬,直到与另一个节点p在同一高度,
再判断当前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 {
public:
//代码优化:使用unordered_map代替map(map是平衡二叉树实现)
//2:错因:map需要使用引用传递&才能将改变后的值传出
void findfather(TreeNode* root,unordered_map<TreeNode*,TreeNode*>&f,TreeNode* fa){
if(root==NULL)return ;
f[root]=fa;
findfather(root->left,f,root);
findfather(root->right,f,root);
}
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
//记录各个节点的父节点
//先找到p,q所在深度
unordered_map<TreeNode*,TreeNode*>f;
findfather(root,f,nullptr);
int lenp=0;
int lenq=0;
TreeNode* p1=p;
TreeNode*q1=q;
while(p1!=root){//深度从0-(n-1)
lenp++;
p1=f[p1];
}
while(q1!=root){
lenq++;
q1=f[q1];
}
//让深度较深的往上走到相同深度
TreeNode* p2=p;
TreeNode*q2=q;
while(lenp!=lenq){
lenp>lenq? p2=f[p2]:q2=f[q2];
lenp>lenq? lenp--:lenq--;
}
while(p1!=nullptr &&p2!=nullptr){
if(p2==q2) return p2;
else{
p2=f[p2];
q2=f[q2];
}
}
return NULL;
}
};
注意点:
//代码优化:使用unordered_map代替map(map是平衡二叉树实现)
//2:错因:map需要使用引用传递&才能将改变后的值传出