题目
输入两棵二叉树A和B,判断B是不是A的子结构。(约定空树不是任意一个树的子结构)
B是A的子结构, 即 A中有出现和B相同的结构和节点值。
思路一
本来想着的是找到中序遍历的结果,如果后面的中序遍历是前面的中序遍历的子串,这样一定结构是相同的。
代码
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
string inorderTraverse(TreeNode *root){
stack<TreeNode *> q;
string ans = "";
TreeNode *cur;
q.push(root);
while(!q.empty()){
while((cur = q.top()) && cur!= NULL) {
q.push(cur -> left);
}
q.pop();
if(!q.empty()){
cur = q.top();
q.pop();
if(cur->val < 0) {
ans +='-';
ans += -cur->val + '0';
}else{
ans += cur->val + '0';
}
ans+='#';
q.push(cur->right);
}
}
return ans;
}
bool isSubStructure(TreeNode* A, TreeNode* B) {
string InOrderA = inorderTraverse(A);
cout<<InOrderA<<endl;
string InOrderB = inorderTraverse(B);
cout<<InOrderB<<endl;
if(InOrderA.find(InOrderB) != string::npos && InOrderB.length() > 0) return true;
return false;
}
};
问题
这种做法只能在于没有重复的数字,在有重复的数字的情况下,会挂掉。例如下面这个测试用例
[2,3,2,1]
[3,null,2,2]
这个的输出结果。因此这种思路是不对的。
思路
需要一个个点进行比较
class Solution {
public:
bool isContain(TreeNode * A, TreeNode * B){
if(B == NULL) return true;
if(A == NULL || A->val != B->val) return false;
return isContain(A->left, B->left) && isContain(A->right, B->right);
}
bool isSubStructure(TreeNode* A, TreeNode* B) {
if(A == NULL || B == NULL) return false;
return isContain(A, B) || isSubStructure(A->left , B) || isSubStructure(A->right, B);
}
};