给定彼此独立的两棵二叉树,树上的节点值两两不同,判断 t1 树是否有与 t2 树完全相同的子树。
子树指一棵树的某个节点的全部后继节点
数据范围:树的节点数满足
,树上每个节点的值一定在32位整型范围内
进阶:空间复杂度:
,时间复杂度
import java.util.*;
/*
* public class TreeNode {
* int val = 0;
* TreeNode left = null;
* TreeNode right = null;
* public TreeNode(int val) {
* this.val = val;
* }
* }
*/
public class Solution {
//遍历主树
//若数值相等,参试遍历同时遍历树进行判断
TreeNode sub=null;
public boolean check(TreeNode root1,TreeNode root2){
if(root1==null&&root2==null){
return true;
}
else if(root1==null||root2==null){
return false;
}
else{
if(root1.val!=root2.val){
return false;
}
else{
return check(root1.left,root2.left)&&check(root1.right,root2.right);
}
}
}
public boolean preOrder(TreeNode root){
if(root!=null){
if(root.val==sub.val){
if(check(root,sub)){
return true;
}
else return false;
}
return preOrder(root.left)||preOrder(root.right);
}
else return false;
}
public boolean isContains (TreeNode root1, TreeNode root2) {
if(root2==null)return true;
sub=root2;
//默认子树不空
return preOrder(root1);
}
}
public boolean isContains (TreeNode root1, TreeNode root2) {
// write code here
if(root1==null && root2==null){
return true;
}
if(root1==null||root2==null){
return false;
}
if(root1.val==root2.val){
return isSame(root1 ,root2);
}
return isContains(root1.left ,root2) || isContains(root1.right ,root2);
}
public boolean isSame(TreeNode root1 ,TreeNode root2){
if(root1==null && root2==null){
return true;
}
if(root1==null || root2==null){
return false;
}
if(root1.val!=root2.val){
return false;
}
return isSame(root1.left ,root2.left) && isSame(root1.right,root2.right);
} public class Solution {
/**
*
* @param root1 TreeNode类
* @param root2 TreeNode类
* @return bool布尔型
*/
public boolean isContains (TreeNode root1, TreeNode root2) {
// write code here
String str1 = serialByPre(root1);
String str2 = serialByPre(root2);
return getIndexOf(str1,str2) != -1;
}
public String serialByPre(TreeNode head){
if (head == null){
return "#!";
}
String res = head.val + "!";
res += serialByPre(head.left);
res += serialByPre(head.right);
return res;
}
//kmp
public int getIndexOf(String s,String m){
if (s == null || m == null || m.length() < 1 || s.length() < m.length()){
return -1;
}
char[] sres = s.toCharArray();
char[] mres = m.toCharArray();
int si = 0;
int mi = 0;
int[] next = getNextArray(mres);
while (si < sres.length && mi < mres.length ){
if (sres[si] == mres[mi]){
si++;
mi++;
}else if (next[mi] == -1){
si ++;
}else{
mi = next[mi];
}
}
return mi == mres.length ? si -mi :-1;
}
public int[] getNextArray(char[] ms){
if (ms.length == 1){return new int[] {-1};}
int[] next = new int[ms.length];
next[0] = -1;
next[1] = 0;
int pos = 2;
int cn = 0;
while (pos < next.length){
if (ms[pos - 1 ] == ms[cn]){
next[pos ++] = ++cn;
}else if (cn > 0){
cn = next[cn];
}else{
next[pos++] = 0;
}
}
return next;
}
} //判断两棵树是否相同
public boolean isTheSame (TreeNode root1, TreeNode root2) {
if (root1 == null && root2 == null) {
return true;
}
if ((root1 != null && root2 == null) || (root1 == null && root2 != null)) {
return false;
}
if (root1.val != root2.val) {
return false;
}
return isTheSame(root1.left, root2.left) && isTheSame(root1.right, root2.right);
}
public boolean isContains (TreeNode root1, TreeNode root2) {
// write code here
if (root1 == null) {
return false;
}
//再添加一个递归结构,遍历找到合适的节点
return isTheSame(root1, root2) || isContains(root1.right, root2) || isContains(root1.left, root2);
} public boolean isContains (TreeNode root1, TreeNode root2) {
//判断r1是否包含r2?
if(root1==null) return false;
if(root1.val!=root2.val)//两个根节点不想等,则用root1的左右子树分别和root2比较
return isContains(root1.left,root2)||isContains(root1.right,root2);
else//root1和root2相同,继续对比
return isSame(root1,root2);
}
public boolean isSame(TreeNode root1,TreeNode root2){
if(root1==null&&root2==null) return true;
if(root1==null||root2==null) return false;
//两个根节点都不为空,继续比较
return (root1.val==root2.val)&&isSame(root1.left,root2.left)&&isSame(root1.right,root2.right);
} public class Solution {
public boolean isContains (TreeNode root1, TreeNode root2) {
if (root1 == null) return false;
return isEquals(root1, root2) || isContains(root1.left, root2) || isContains(root1.right, root2);
}
private boolean isEquals(TreeNode root1, TreeNode root2) {
if (root1 == null && root2 == null) return true;
if (root1 == null || root2 == null) return false;
if (root1.val != root2.val) return false;
return isEquals(root1.left, root2.left) && isEquals(root1.right, root2.right);
}
} public class Solution {
/**
*
* @param root1 TreeNode类
* @param root2 TreeNode类
* @return bool布尔型
*/
public boolean isContains (TreeNode root1, TreeNode root2) {
// write code here
if(root1 == null && root2 == null){return true;}
if(root1 == null){return false;}
Deque<TreeNode> queue = new LinkedList<>();
queue.offerLast(root1);
while(!queue.isEmpty()){
int len = queue.size();
for(int i = 0; i < len; ++i){
TreeNode root = queue.pollFirst();
if(helper(root, root2)){
return true;
}else{
if(root.left != null){queue.offerLast(root.left);}
if(root.right != null){queue.offerLast(root.right);}
}
}
}
return false;
}
public boolean helper(TreeNode root1, TreeNode root2){
if(root1 != null && root2 != null){
return root1.val == root2.val &&
helper(root1.left, root2.left) &&
helper(root1.right, root2.right);
}else if(root1 == null && root2 == null){
return true;
}
return false;
}
} import java.util.*;
public class Solution {
public boolean isContains (TreeNode root1, TreeNode root2) {
// write code here
StringBuilder builder1 = new StringBuilder();
StringBuilder builder2 = new StringBuilder();
preOrder(root1,builder1);
preOrder(root2,builder2);
if(builder1.toString().contains(builder2.toString())){
return true;
}else {
return false;
}
}
//中序遍历并填充stringbuilder
static void preOrder(TreeNode treeNode,StringBuilder stringBuilder){
if(treeNode==null){
return;
}
preOrder(treeNode.left,stringBuilder);
stringBuilder.append(treeNode.val);
preOrder(treeNode.right,stringBuilder);
}
}