题目: 输入两棵二叉树A和B,判断B是不是A的子结构。(约定空树不是任意一个树的子结构)
B是A的子结构, 即 A中有出现和B相同的结构和节点值。
示例 1:
输入:A = [1,2,3], B = [3,1]
输出:false
示例 2:
输入:A = [3,4,5,1,2], B = [4,1]
输出:true
思路:
这道题目和之前做的LeetCode572.另一棵树的子树这道题有点像,但是完全不是一道题
572题中,也是寻找子树,但是这个子树是指从你当前节点到叶子节点全部一样并且后边也都是NULL。
而这道题目不需要,只需要判断含有子树就行了,下边画图说明两道题目有什么不同之处。
在下图中,subroot在572题目中返回的是false,在剑指offer26中返回的是true
题解:题目中说了,如果有一个为空,那么直接false就行了
下边就分成两种情况讨论了,如果从头节点开始val就相等,那么一直比较root和subroot的左右子树是不是都相等
如果是返回true,如果不相等,那么就开始递归遍历root的左子树和root的右子树和subroot是不是匹配了
在issame中,如果subroot==NULL,返回false是因为已经有头节点一样了,这是遍历到左子树或者右子树的节点了
而该题目中,只是找有子结构的,并不需要从节点开始下边要全部一样。但是如果root为空时,subroot不为空,那么就有问题了
struct TreeNode {int val;TreeNode* left;TreeNode* right;TreeNode(int x):val(x),left(NULL),right(NULL){}
};class Solution {
public:bool isSubStrcture(TreeNode* root,TreeNode* subroot) {if (root == NULL || subroot == NULL)return false;if ((root->val == subroot->val) && issame(root->left, subroot->left)&& (issame(root->right, subroot->right)))return true;return isSubStrcture(root->left, subroot) || isSubStrcture(root->right, subroot);}bool issame(TreeNode* root,TreeNode* subroot) {if (subroot == NULL)return true;if (root == NULL) return false;if (root->val == subroot->val) {return issame(root->left, subroot->left) && issame(root->right, subroot->right);}else {return false;}}
};int main() {TreeNode* A = new TreeNode(1);TreeNode* B = new TreeNode(2);TreeNode* C = new TreeNode(3);A->left = B;A->right = C;TreeNode* a = new TreeNode(3);TreeNode* b = new TreeNode(1);a->left = b;Solution ss;cout << ss.isSubStrcture(A, a) << endl;return 0;
}