本来不打算写的哈哈哈但是发现这一道递归我是有思路的!!自己能想到一些方向!我真棒!所以记录一下哈哈哈
我的思路:
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;}
};
递归加油!!!!再坚持一下!!!