• 树的子结构


    时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M

    题目描述

    输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)
     
    知识铺垫:
      先来看下子树和子结构的概念
        子树:只要包含了一个节点,就得包含这个节点下的所有节点
        子结构:包含了一个节点,可以只取左子树或右子树,或者不取,强调结构上的一致
      (可参考:https://blog.csdn.net/wushuomin/article/details/79943737)
     思路:
      一颗大树A,一颗小树B,首先判断A的根节点是否与B的根节点相同,不相同,就依次去A根节点的左子树、右子树上查找,如果存在(假设A中与B的根节点相等的节点为D),此时需要判断的就是D的左子树、右子树是否与B的根节点的左子树、右子树相同节点结构,终止条件:如果B先访问到头了,即小树B先达到NULL,说明B就是A的子结构,如果大树A达到NULL,说明就不是A的子结构。
     
      采用递归的方式
    /*
    struct TreeNode {
        int val;
        struct TreeNode *left;
        struct TreeNode *right;
        TreeNode(int x) :
                val(x), left(NULL), right(NULL) {
        }
    };*/
    class Solution {
    public:
        bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoot2)
        {
            bool result = false;
            if(pRoot1 != NULL && pRoot2 != NULL)
            {
                if(pRoot1->val == pRoot2->val)
                {
                    //该根节点作为起点判断是否包含pRoot2
                    result = judgeSubTree(pRoot1,pRoot2);
                }
                //如果没有找到,就去该节点的左子树中找
                if(!result)
                {
                    result = HasSubtree(pRoot1->left,pRoot2);
                }
                //如果还没有找到,就去该节点的右子树中找
                if(!result)
                {
                    result = HasSubtree(pRoot1->right,pRoot2);
                }
                 
            }
            return result;
        }
    private:
        bool judgeSubTree(TreeNode *node1,TreeNode *node2)
        {
            if(node2 == NULL)
                return true;
            if(node1 == NULL)
                return false;
             if(node1->val != node2->val)
             {
                 return false;
             }
            return judgeSubTree(node1->left,node2->left)
                && judgeSubTree(node1->right,node2->right);
        }
    };
    在judgeSubTree函数中对node1->val 与node2->val判断是否相等是有必要的,应为该函数是一个递归函数,下面递归调用的时候,还是要判断传进去的两个节点的值是否相等
    另一种写法:
    /*
    struct TreeNode {
        int val;
        struct TreeNode *left;
        struct TreeNode *right;
        TreeNode(int x) :
                val(x), left(NULL), right(NULL) {
        }
    };*/
    class Solution {
    public:
        bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoot2)
        {
            if(pRoot1 == NULL || pRoot2 == NULL)
            {
                return false;
            }
            return judeSubTree(pRoot1,pRoot2) 
                || judeSubTree(pRoot1->left,pRoot2)
                ||judeSubTree(pRoot1->right,pRoot2);
        }
        bool judeSubTree(TreeNode* node1,TreeNode * node2)
        {
            if(node2 == NULL)
                return true;
            if(node1 == NULL)
                return false;
            if(node1->val != node2->val)
                return judeSubTree(node1->left,node2) || 
                judeSubTree(node1->right,node2);
            return judeSubTree(node1->left,node2->left)&&
                judeSubTree(node1->right,node2->right);
        }
    };

    子结构包含与子树,子树会要求更加严格,不仅结构相同,节点的值也要相同,只需要对其值判断相等,不能就直接返回false即可

    判断是否为子树:

    /*
    struct TreeNode {
        int val;
        struct TreeNode *left;
        struct TreeNode *right;
        TreeNode(int x) :
                val(x), left(NULL), right(NULL) {
        }
    };*/
    class Solution {
    public:
        bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoot2)
        {
            if(pRoot1 == NULL || pRoot2 == NULL)
            {
                return false;
            }
            return judeSubTree(pRoot1,pRoot2) 
                || judeSubTree(pRoot1->left,pRoot2)
                ||judeSubTree(pRoot1->right,pRoot2);
        }
        bool judeSubTree(TreeNode* node1,TreeNode * node2)
        {
            if(node2 == NULL)
                return true;
            if(node1 == NULL)
                return false;
            if(node1->val != node2->val)
                return false;
            return judeSubTree(node1->left,node2->left)&&
                judeSubTree(node1->right,node2->right);
        }
    };
  • 相关阅读:
    导航栏的修改
    [题解](背包)luogu_P4095 eden的新背包问题
    [題解](貪心/堆)luogu_P2107小Z的AK計劃
    [題解](最短路)luogu_P2384最短路
    [題解](單調隊列dp)luogu_P1725琪露諾
    [題解](單調隊列/水)luogu_P3088擠奶牛
    [題解](單調隊列dp)【2016noip福建夏令營】探險
    [題解](水/最短路)出题人大战工作人员
    [题解](最短路)最短路点数
    [題解]luogu_P1613跑路(最短路/倍增)
  • 原文地址:https://www.cnblogs.com/whiteBear/p/12523524.html
Copyright © 2020-2023  润新知