题目
检查子树。你有两棵非常大的二叉树:T1,有几万个节点;T2,有几万个节点。设计一个算法,判断 T2 是否为 T1 的子树。
如果 T1 有这么一个节点 n,其子树与 T2 一模一样,则 T2 为 T1 的子树,也就是说,从节点 n 处把树砍断,得到的树与 T2 完全相同。
示例1:
输入:t1 = [1, 2, 3], t2 = [2]
输出:true
示例2:
输入:t1 = [1, null, 2, 4], t2 = [3, 2]
输出:false
提示:
树的节点数目范围为[0, 20000]。
方法一
t2是t1的子集所以若t2中包含t1,则如果能我们找到t1和t2相同的val并且递归遍历 直到t2等于null(t2遍历完) 如果都相等,则证明t2是t1的子集。
具体实现
递归终止条件
1.当t1等于null并且t2不等于null 说明t1中一定不包含t2.
2.当t1中包含t2 并且t2为null 说明t1中一定包含t2.
如果找到t1和t2相同,则递归判断t1的左节点和t2的左节点是否相等,t1的右节点和t2的右节点是否相等,都相等则t1包含t2
如果没有找到t1和t2相同,那就继续找,递归遍历t1的左节点是否等于t2,t1的右节点是否等于t2.都找不到则证明t1不包含t2
递归真的很佛系,如果你觉得麻烦,请看第二种方法
/**
* @description: 检查子树
* @Author MRyan
* @Date 2020/6/18 09:44
* @Version 1.0
*/
class Solution {
public boolean checkSubTree(TreeNode node1, TreeNode node2) {
return solve(node1, node2);
}
public boolean solve(TreeNode node1, TreeNode node2) {
if (node2 == null) {
return true;
}
if (node1 == null && node2 != null) {
return false;
}
if (node1.val == node2.val) {
return solve(node1.left, node2.left) && solve(node1.right, node2.right);
} else {
return solve(node1.left, node2) || solve(node1.right, node2);
}
}
}
方法二
巧妙运用工具。
具体实现:
中序遍历t1得到t1的字符串。
中序遍历t2得到t2的字符串。
将求树t1是否包含树t2转换为求字符串t1是否包含字符串t2。
利用StringBuffer 简单!
/**
* @description: 检查子树
* @Author MRyan
* @Date 2020/6/18 09:44
* @Version 1.0
*/
class Solution {
public StringBuffer stringBuffer1 = new StringBuffer("");
public StringBuffer stringBuffer2 = new StringBuffer("");
public boolean checkSubTree(TreeNode t1, TreeNode t2) {
solve(t1, stringBuffer1);
solve(t2, stringBuffer2);
boolean check = check(stringBuffer1.toString(), stringBuffer2.toString());
return check;
}
public boolean check(String s1, String s2) {
return s1.contains(s2);
}
public void solve(TreeNode root, StringBuffer stringBuffer) {
if (root == null) {
return;
}
stringBuffer.append(root.val);
solve(root.left, stringBuffer);
solve(root.right, stringBuffer);
}
}