学习随笔
公共祖先问题
- dfs
- 递归
题目具体链接
题目描述:给定两个节点找公共祖先,重点是体会后序遍历在其中的作用
- 递归
具体代码
class Solution {
public:
TreeNode* ans;
bool dfs(TreeNode* root, TreeNode* p, TreeNode* q)//不会停止它会遍历完所有的节点,由下而上
//后续遍历,得到
{
if(root==0) return false;
bool fp=dfs(root->left,p,q);
bool fq=dfs(root->right,p,q);
if((fp&&fq)||(root->val==p->val||root->val==q->val)&&(fq||fp))
{
ans=root;
}
return fp||fq||root->val==p->val||root->val==q->val;//在本树中找到一个
}
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
dfs(root, p, q);
return ans;
}
};
class Solution {
public:
TreeNode* ans;
int dfs(TreeNode* root, TreeNode* p, TreeNode* q)
{
if(root==0) return 0;
bool fq=0,fp=0;
int tl=dfs(root->left,p,q);
int tr=dfs(root->right,p,q);
if(tl==1) fp=1;
else if(tl==2) fq=1;
if(tr==1) fp=1;
else if(tr==2) fq=1;
if((fp&&fq)||(root->val==p->val||root->val==q->val)&&(fq||fp))
{
ans=root;
}
if(fp||root->val==p->val) return 1;
else if(fq||root->val==q->val) return 2;
else return 0;
}
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
dfs(root, p, q);
return ans;
}
};
# 学习产出:
- 关键是找好 递归传递的状态是什么?怎么传递的?
状态就是有或无,如果两颗子树都有的话,那赋值 ans
若是只有一颗有,继续往上面传送状态
若是都没有,直接废弃。
- 我们解决递归问题首先要找到子问题,这里的子问题是找到p,q节点是否在子树中,我们用递归方法,假设已经找到了,我们直接把fp,fq拿来用,找到之后,p,q在这棵树中有几种情况? **两种**把这两种情况都列出来,就找到了 ans。最后我们要解决的问题是,dfs的返回值是多少。其实dfs可以返回明确的值比如-1代表p找到了, 1代表q找到了,这样可以更加明确一点,让读者知道。
- 你可能会疑惑这样找出来的公共祖先深度是否是最大的。其实是最大的,因为我们是自底向上从叶子节点开始更新的,所以在所有满足条件的公共祖先中一定是深度最大的祖先先被访问到,且由于 fxf_xfx 本身的定义很巧妙,在找到最近公共祖先 xxx 以后,fxf_xfx 按定义被设置为 true ,即假定了这个子树中只有一个 ppp 节点或 qqq 节点,因此其他公共祖先不会再被判断为符合条件。
- 代码块2可能读起来更加容易理解一点。