题解 | 树的子结构
树的子结构
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树使用相同方法就行(目的是对应位置一致)。

