题解 | 树的子结构

树的子结构

https://www.nowcoder.com/practice/6e196c44c7004d15b1610b9afca8bd88

/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};*/
#include <queue>
class Solution {
  public:
    bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoot2) {
        if (!pRoot1 || !pRoot2) return false;
        queue<TreeNode*> q;
        q.push(pRoot1);
        while (!q.empty()) {
            TreeNode* temp = q.front();
            q.pop();
            if (temp->left) q.push(temp->left);
            if (temp->right) q.push(temp->right);
            if (temp->val == pRoot2->val) {
                queue<TreeNode*>q1, q2;
                bool ans = true;
                q1.push(temp), q2.push(pRoot2);
                while (!q1.empty() && !q2.empty()) {
                    TreeNode* t1 = q1.front();
                    TreeNode* t2 = q2.front();
                    q1.pop(), q2.pop();
                    if (t1->val != t2->val) {
                        ans = false;
                        break;
                    };
                    if (t1->left&&t2->left) q1.push(t1->left);
                    if (t1->right&&t2->right) q1.push(t1->right);
                    if (t2->left) q2.push(t2->left);
                    if (t2->right) q2.push(t2->right);
                    if (q1.empty() && !q2.empty()) {
                        ans = false;
                        break;
                    }
                }
                if (ans)
                    return true;
            }
        }
        return false;
    }
};

方法一(二重层次遍历):对每个A树层次遍历节点,然后看以这个节点为根节点的树对应B节点有的节点是否相等(再次使用层次遍历,这时一步一步完全对应)。

注意B树没有的节点A树可以有,但是它们不比较,也就不放入子级层次遍历的A树队列中。

/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};*/
class Solution {
  public:
    bool checkOne(TreeNode* pRoot1, TreeNode* pRoot2) {
		if(pRoot1==nullptr&&pRoot2!=nullptr) return false;
		if(pRoot2==nullptr) return true;
        bool flag1 = false, flag2 = false;
        if(pRoot1->val!=pRoot2->val) return false;
		flag1 = checkOne(pRoot1->left, pRoot2->left);
		flag2 = checkOne(pRoot1->right, pRoot2->right);
		return flag1&&flag2;
    }

    bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoot2) {
        if (pRoot1 == nullptr || pRoot2 == nullptr)return false;
        bool flag1 = false, flag2 = false, flag3 = false;
        if (pRoot1->val == pRoot2->val) {
            flag1 = checkOne(pRoot1, pRoot2);
        }
        flag2 = HasSubtree(pRoot1->left, pRoot2);
        flag3 = HasSubtree(pRoot1->right, pRoot2);
		//std::cout<<flag1<<" "<<flag2<<" "<<flag3<<std::endl;
        return flag1 || flag2 || flag3;
    }
};

方法二(迭代):

因为处理顺序只需要两者一致就行,所以前序中序后序都可以。需要注意的点和方法一相同(二级时刻以B树为主体,因为A树有B树没有的部分(比如B树右节点为空而A树有)并不影响B树在A树中)。

两个方法都是双层遍历,一级遍历A树,二级(子级)遍历B树。因此只要是遍历就行,它们的遍历方法可以混着来,只要二级遍历A树和B树使用相同方法就行(目的是对应位置一致)。

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务