判断一棵树是不是另一颗树的子树
首先可以先判断根节点是否相同,找到根节点相同的之后,再判断其左右子树是否相同。
当出现A树有某子节点,B树没有的时候,也有可能是true。
反之不行
public class Solution {
public boolean HasSubtree(TreeNode root1,TreeNode root2) {
if(root1==null || root2==null){
return false;
}
if(root1.val == root2.val && isContain(root1,root2)){
return true;
}
return HasSubtree(root1.left,root2) || HasSubtree(root1.right,root2);
}
public boolean isContain(TreeNode node1,TreeNode node2){
if(node1 == null && node2!= null){
return false;
}
if(node2 == null){
return true;
}
return node1.val == node2.val && isContain(node1.left,node2.left) &&isContain(node1.right,node2.right);
}
}
第二种方法:
首先先把两棵树进行序列化,化成字符串的形式(注意空子树要填#)
然后问题就转换成了求子串的问题。
用KMP算法来解这个问题。
时间复杂度比较小
public boolean HasSubtree(TreeNode root1,TreeNode root2) {
String a = serial(root1);
String b = serial(root2);
return getIndexOf(a,b);
}
//树的序列化
public static String serial(TreeNode head){
if(head == null){
return "#";
}
String res = head.val+"";
res += serial(head.left);
res += serial(head.right);
return res;
}
//准备用KMP算法判断一个是否是另一个的子串
//先弄出Next数组
public static int[] getNextArray(char[] ms){
if(ms.length == 1){
return new int[]{-1};
}
int[] nextArr = new int[ms.length];
nextArr[0]=-1;
nextArr[1]=0;
int right = 2;
int left = 0;
while(right<nextArr.length){
if(ms[right-1]==ms[left]){
nextArr[right++] = ++left;
}else if(left>0){
left = nextArr[left];
}else{
nextArr[right++]=0;
}
}
return nextArr;
}
//判断两个String是否是子串
public static boolean getIndexOf(String s, String m) {
if (s == null || m == null || m.length() < 1 || s.length() < m.length()) {
return false;
}
char[] ss = s.toCharArray();
char[] ms = m.toCharArray();
int[] nextArr = getNextArray(ms);
int index = 0;
int mi = 0;
while (index < ss.length && mi < ms.length) {
if (ss[index] == ms[mi]) {
index++;
mi++;
} else if (nextArr[mi] == -1) {
index++;
} else {
mi = nextArr[mi];
}
}
return mi == ms.length;
}
}
在这里插入代码片