2021.3.17学习随笔_dfs_递归后序遍历

学习随笔

公共祖先问题

  • 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可能读起来更加容易理解一点。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值