问题
来自力扣:
输入两棵二叉树A和B,判断B是不是A的子结构。(约定空树不是任意一个树的子结构)
B是A的子结构, 即 A中有出现和B相同的结构和节点值。
例如:
给定的树 A:
3
/ \
4 5
/ \
1 2
给定的树 B:
4
/
1
返回 true,因为 B 与 A 的一个子树拥有相同的结构和节点值。
示例 1:
输入:A = [1,2,3], B = [3,1]
输出:false
示例 2:
输入:A = [3,4,5,1,2], B = [4,1]
输出:true
我的代码
#include <iostream>
using namespace std;
#include <algorithm>
#include <vector>
#include<queue>
#include <typeinfo>
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
class Solution {
public:
bool isSubStructure(TreeNode* A, TreeNode* B) {
queue <TreeNode> qnode;
if (A == NULL || B == NULL) return false;
qnode.push(*A);
while (!qnode.empty()) {
if(issubstructure(qnode.front(), *B)) return true;
if (qnode.front().left != NULL)
qnode.push(*(qnode.front().left));
if (qnode.front().right != NULL)
qnode.push(*(qnode.front().right));
qnode.pop();
}
return false;
}
bool issubstructure(TreeNode A, TreeNode B) {
if (B.val == A.val) {
if (B.left == NULL || (A.left!= NULL &&issubstructure(*(A.left),*(B.left)))) {
if (B.right== NULL || (A.right != NULL && issubstructure(*(A.right), *(B.right)))) {
return true;
}
}
}
return false;
}
};
int main() {
TreeNode* root=NULL;
root = new TreeNode(3);
root->left = new TreeNode(4);
root->right = new TreeNode(5);
root->left->left = new TreeNode(1);
root->left->right = new TreeNode(2);
TreeNode* root2 = NULL;
root2 = new TreeNode(4);
root2->left = new TreeNode(2);
TreeNode* root3= NULL;
Solution mysolution;
bool s = mysolution.isSubStructure(root3,root2);
cout << s;
return 0;
}
步骤:
- 定义队列qnode
- 当A或B是空时,return false。
- 当步骤2没return时,将A的头结点压入队列qnode。
- 当队列非空时,将队列首元素和B作为参数,调用递归函数issubstructure()。如果返回值是true,则return true。
- 当步骤4没return时,检查队列首元素是否有子节点,有则压入队列中,然后pop首元素。
- 如果while循环结束了,证明没找到子结构,return false。
递归函数issubstructure():
- 先检查值是否相同。
- 再检查左分支是否相同(或者B的左分支为NULL)。
- 最后检查右分支是否相同(或者B的右分支为NULL)。
示例代码
bool solve(TreeNode *A, TreeNode *B) {
if (A->val != B->val) {
return false;
}
bool la = (A->left != NULL), lb =(B->left != NULL);
bool ra = (A->right != NULL), rb =(B->right != NULL);
if (la && ra) {
if (lb && rb) {
return solve(A->left, B->left) && solve(A->right, B->right);
} else if (lb) {
return solve(A->left, B->left);
} else if (rb) {
return solve(A->right, B->right);
} else {
return true;
}
} else if (la) {
if (lb && rb) {
return false;
} else if (lb) {
return solve(A->left, B->left);
} else if (rb) {
return false;
} else {
return true;
}
} else if (ra) {
if (lb && rb) {
return false;
} else if (lb) {
return false;
} else if (rb) {
return solve(A->right, B->right);
} else {
return true;
}
} else {
if (lb == false && rb == false) {
return true;
} else {
return false;
}
}
}
bool judge(TreeNode *A, TreeNode *B) {
queue<TreeNode*> Q;
Q.push(A);
bool flag = false;
while(!Q.empty()) {
TreeNode *node = Q.front();
Q.pop();
if (node->val == B->val) {
flag = flag || solve(node, B);
}
if (node->left) {
Q.push(node->left);
}
if (node->right) {
Q.push(node->right);
}
}
return flag;
}
class Solution {
public:
bool isSubStructure(TreeNode* A, TreeNode* B) {
if (A == NULL || B == NULL) {
return false;
}
return judge(A, B);
}
};
示例代码也用了队列和递归,且多用了我一个函数,递归函数看着比我复杂,不过本质思路差不多。