zoukankan      html  css  js  c++  java
  • 【剑指Offer面试编程题】题目1520:树的子结构--九度OJ

    题目描述:

    输入两颗二叉树A,B,判断B是不是A的子结构。

    输入:

    输入可能包含多个测试样例,输入以EOF结束。
    对于每个测试案例,输入的第一行一个整数n,m(1<=n<=1000,1<=m<=1000):n代表将要输入的二叉树A的节点个数(节点从1开始计数),m代表将要输入的二叉树B的节点个数(节点从1开始计数)。接下来一行有n个数,每个数代表A树中第i个元素的数值,接下来有n行,第一个数Ki代表第i个节点的子孩子个数,接下来有Ki个树,代表节点i子孩子节点标号。接下来m+1行,与树A描述相同。

    输出:

    对应每个测试案例,
    若B是A的子树输出”YES”(不包含引号)。否则,输出“NO”(不包含引号)。

    样例输入:

    7 3
    8 8 7 9 2 4 7
    2 2 3
    2 4 5
    0
    0
    2 6 7
    0
    0
    8 9 2
    2 2 3
    0
    0
    
    1 1
    2
    0
    3
    0
    样例输出:

    YES
    NO
    【解题思路】一看到树,第一想法就是递归,虽然递归的效率确实不高,但在OJ上讲究时间效率,有时候配合适当的剪枝能快速AC。本题需要两层递归,首先我们要确定A树的哪个子树与B树进行比照,也就是确定A树的子节点,这是第一层递归;另外,在比较的时候我们也需要用到树的递归,对每一个节点进行比较。两层递归的顺序都是树的先序遍历的顺序。

         中间有一点点小技巧,在第一层递归时,我们要在确定B树为子树的时候果断停止递归,避免过多的迭代。

    AC code:

    #include <cstdio>
    #include <vector>
    using namespace std;
     
    struct st
    {
      int val;
      st *lc;
      st *rc;
    };
    bool flg=false,reflg=false;
     
    void check(st *s1,st*s2)
    {
      if(s1->val!=s2->val)
      {
        flg=true;
        return ;
      }
      if(s2->lc==NULL && s2->rc==NULL)
        return ;
      if(s1->lc!=NULL && s2->lc!=NULL)
        check(s1->lc,s2->lc);
      else if(s1->rc!=NULL && s2->rc!=NULL)
        check(s1->rc,s2->rc);
      else
      {
        flg=true;
        return ;
      }
    }
     
    void fill(vector<st> &veca,const int&n)
    {
      st ss;
      ss.val=0;
      ss.lc=ss.rc=NULL;
      veca.push_back(ss);
      for(int i=0;i<n;++i)
      {
        scanf("%d",&ss.val);
        veca.push_back(ss);
      }
      for(int i=1;i<=n;++i)
      {
        int k,tt;
        scanf("%d",&k);
        for(int j=0;j<k;++j)
        {
          scanf("%d",&tt);
          if(j==0)
            veca[i].lc=&veca[tt];
          else
            veca[i].rc=&veca[tt];
        }
      }
    }
     
    void chk(st *st1,st *st2)
    {
      if(st1==NULL)
        return;
      flg=false;
      check(st1,st2);
      if (!flg) return;
      if(st1->lc && flg)
        chk(st1->lc,st2);
      if(st1->rc && flg)
        chk(st1->rc,st2);
    }
     
    int main()
    {
      int n,m;
      while(scanf("%d%d",&n,&m)!=EOF)
      {
        vector<st> veca,vecb;
        fill(veca,n);
        fill(vecb,m);
        st* st1=&veca[1],*st2=&vecb[1];
        flg=false;
        if(!st2)flg=false;
        else chk(st1,st2);
        if(flg)
          printf("NO
    ");
        else
          printf("YES
    ");
      }
      return 0;
    }
    /**************************************************************
        Problem: 1520
        User: huo_yao
        Language: C++
        Result: Accepted
        Time:10 ms
        Memory:1024 kb
    ****************************************************************/
    题目链接:http://ac.jobdu.com/problem.php?pid=1520

    九度-剑指Offer习题全套答案下载:http://download.csdn.net/detail/huoyaotl123/8276299



  • 相关阅读:
    bzoj3996
    bzoj3157 3516
    bzoj1937
    bzoj1532
    bzoj3572
    bzoj1453
    bzoj3205
    bzoj2595
    关于高斯消元解决xor问题的总结
    linux查找和替换命令
  • 原文地址:https://www.cnblogs.com/huoyao/p/4248903.html
Copyright © 2011-2022 走看看