🔥题目
输入两棵二叉树A和B,判断B是不是A的子结构。(约定空树不是任意一个树的子结构)
给定的树 A:
3
/ \
4 5
/ \
1 2
给定的树 B:
4
/
1
树B是树A的子结构 >_<!
☘️解析
算法包含两个步骤:
1)对于树A的每个节点(一次子结构递归)
2)以该节点为根结点,匹配树B(一次普通递归)
isSubStructure(A, B)
- 终止条件:
根据题意,A==null或B==null,则直接失败 - 如果B树是A树的子结构,那么只需要满足下面的一种情况即可,因此用
||
连接:
1)以当前节点为根结点,B是A的子结构
2)B是A的左子树的子结构
3)B是A的右子树的子结构
dfs(A, B)
- 终止条件:
1)B==null,说明匹配成功,返回true
2)A==null,说明没得匹配,返回false - 如果匹配成功,下面的条件必须全部满足,因此用
&&
连接:
1)A和B当前节点值相同
2)A和B的左子树匹配成功
3)A和B的右子树匹配成功
🧊代码
class Solution {
public boolean isSubStructure(TreeNode A, TreeNode B) {
if (A == null || B == null) {
return false;
}
return dfs(A, B) || isSubStructure(A.left, B) || isSubStructure(A.right, B);
}
private boolean dfs(TreeNode A, TreeNode B) {
if (B == null) {
return true;
}
if (A == null) {
return false;
}
return A.val == B.val && dfs(A.left, B.left) && dfs(A.right, B.right);
}
}
🌸补充
时间复杂度为 O(mn) 。其中m为树A的节点数,n为树B的节点数。
可以这么理解:本题使用了双递归,第一种递归访问了树A的所有节点,第二种递归访问了树B的所有节点——有点双重for循环的意味。