本来不打算写的哈哈哈但是发现这一道递归我是有思路的!!自己能想到一些方向!我真棒!所以记录一下哈哈哈
我的思路:
1、祖先一定是自身或往上找,所以如何逆着走呢?
2、3种情况:
有一个结点是另一个结点父节点 ,那么返回其中一个结点本身;
这两个结点是兄弟结点,那么返回他们的父亲结点;(回到上一个问题,怎么找父节点?);
不是父子也不是兄弟,那么就继续往上找。
方法一:递归
看了题解发现,我想的3种情况中,2和3可以合并,也就是往上找的情况。看这个题解是否能明白呢?
因为树的遍历是从上往下,所以方便地递归判断其左右子树,因此解题方法需要立足于从上往下,这和我的思路的不同的。
代码:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if(!root)
return NULL;
if(root==p||q==root)
return root;
TreeNode* leftnode=lowestCommonAncestor(root->left,p,q);
TreeNode* rightnode=lowestCommonAncestor(root->right,p,q);
if(rightnode&&leftnode)return root;
if(leftnode)return leftnode;
if(rightnode)return rightnode;
//如何判断left或right就是最近的点呢?
return NULL;
}
和官方题解的不太一样哈哈哈,我个人比较习惯这种写法
方法二:
真的可以存储父节点欸!用dfs遍历! 是个很奇妙的思路!
代码:
class Solution {
public:
unordered_map<int,TreeNode*>fa;//存储父节点
unordered_map<int,bool>vis;//一个结点的父节点是否是另一个结点的父节点
void dfs(TreeNode* root)
{
if(root->left)
{
fa[root->left->val]=root;
dfs(root->left);
}//把左子树都记录下父节点
if(root->right)
{
fa[root->right->val]=root;
dfs(root->right);
}
}
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if(!root)
return NULL;
dfs(root);//遍历,记录哈希表
while(p!=NULL)
{
vis[p->val]=true;
p=fa[p->val];
}//遍历p的所有父节点
while(q!=NULL)
{
if(vis[q->val])
return q;
q=fa[q->val];
}
return NULL;
}
};
递归加油!!!!再坚持一下!!!