题目
输入两棵二叉树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
思路
需要遍历两次树,
先遍历树A,找到与树B根节点值相同的节点;
对于上述每个找到的节点,遍历树B,比对该树结构与找到的节点之下结构是否相同
遍历树A(识别与树B root值相等的节点):
- 如果B是空,返回false, 因为约定空树不是任意一个树的子结构
- 如果A是空,也返回false.
- 对A每个节点判断:B是否与A值相等
- 递归判断 B是否与A的左孩子子结构相同;B是否与A的右孩子结构相同
遍历找到点对应子树A与树B(对比与B的结构是否相同):
- 当节点B为空,表示树B遍历完,说明B是A的子结构,返回true
- 当节点A为空,表示树A遍历完,说明匹配失败,B不是A的子结构,返回false
- 如果节点A与节点B的值不同,说明不匹配,返回false.
- 递归判断A的左孩子与B的左孩子是否相同;A的右孩子与B的右孩子是否相同
代码实现
class Solution {
public:
bool isSubStructure(TreeNode* A, TreeNode* B) {
if (A == nullptr || B == nullptr) return false;
if (isPart(A, B)) return true; // 对A的每个节点判断是否包含B, 即遍历树B
return isSubStructure(A->left, B) || isSubStructure(A->right, B);
}
bool isPart(TreeNode* A, TreeNode* B) {
if (B == nullptr) return true; // B遍历完 说明A包含B, 返回true
if (A == nullptr) return false; // A遍历完,返回false
if (A->val != B->val) return false;
return isPart(A->left, B->left) && isPart(A->right, B->right);
}
};
总结
- 时间复杂度:O(MN),M、N分别是树A与树B的节点数量