给定两个非空二叉树 s 和 t,检验 s 中是否包含和 t 具有相同结构和节点值的子树。s 的一个子树包括 s 的一个节点和这个节点的所有子孙。s 也可以看做它自身的一棵子树。
示例 1:
给定的树 s:
3
/ \
4 5
/ \
1 2
给定的树 t:
4
/ \
1 2
返回 true,因为 t 与 s 的一个子树拥有相同的结构和节点值。
示例 2:
给定的树 s:
3
/ \
4 5
/ \
1 2
/
0
给定的树 t:
4
/ \
1 2
返回 false。
方法:比较节点
我们可以将给定树的每个节点 tt 作为根,将其作为子树,并将相应子树与给定子树 ss 进行比较,以获得相等性。为了检查相等性,我们可以比较两个子树的所有节点。
为此,我们使用一个函数 traverse(s,t),它遍历给定的树 ss 并将每个节点视为当前正在考虑的子树的根。它还检查当前考虑的两个子树是否相等。为了检查两个子树的相等性,我们使用了 equals(x,y) 函数,它取 xx 和 yy 作为要比较的两个子树的根作为输入,并根据两者是否相等返回 true 或 false。它比较两个子树的所有节点是否相等。首先,它检查两个树的根是否相等,然后递归判断左子树和右子树。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public boolean isSubtree(TreeNode s, TreeNode t) {
if(s == null) return false;
if(s.val == t.val){
if(tranverse(s.left, t.left) && tranverse(s.right, t.right)){
return true;
}
}
return isSubtree(s.left, t) || isSubtree(s.right, t);
}
private boolean tranverse(TreeNode s, TreeNode t){
if(s == null && t == null){
return true;
}else if(s == null || t == null){
return false;
}else if(s.val == t.val){
return tranverse(s.left, t.left) && tranverse(s.right, t.right);
}else{
return false;
}
}
}
复杂度分析
时间复杂度:O(mn)。在最坏的情况下(倾斜树)traverse 需要 O(mn)时间。
空间复杂度:O(n),递归树的深度可以达到 n。n 表示 s 中的节点数。