代码如下
import java.util.Scanner;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
import java.util.Stack;
class TreeNode {
int val;
TreeNode left;
TreeNode right;
public TreeNode(int val) {
this.val = val;
}
}
class ScannerInfo {
int rootNum;
int[][] info;
public ScannerInfo(int rootNum, int[][] info) {
this.rootNum = rootNum;
this.info = info;
}
}
public class Main {
static Map<Integer,TreeNode> cache = new HashMap<>(16);
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while(scanner.hasNext()) {
ScannerInfo bigTreeScannerInfo = scannerInfo(scanner);
TreeNode bigTree = constructTree(bigTreeScannerInfo.rootNum, bigTreeScannerInfo.info);
ScannerInfo smallTreeScannerInfo = scannerInfo(scanner);
TreeNode smallTree = constructTree(smallTreeScannerInfo.rootNum, smallTreeScannerInfo.info);
System.out.printf("%s\n", String.valueOf(isSubTree(bigTree, smallTree)));
}
}
private static boolean isSubTree(TreeNode big, TreeNode small) {
boolean result1 = check(big, small);
boolean result2 = check(big.left, small);
boolean result3 = check(big.right,small);
return result1 || result2 || result3;
}
private static boolean check(TreeNode big, TreeNode small) {
if (small == null) {
return true;
}
if (big == null) {
return false;
}
if (big.val != small.val) {
return check(big.left, small) || check(big.right,small);
}
return check(big.left, small.left) && check(big.right, small.right);
}
private static ScannerInfo scannerInfo(Scanner scanner) {
int treeNum = scanner.nextInt();
int treeRootNum = scanner.nextInt();
int temp = treeNum;
int i = 0;
int[][] info = new int[treeNum][3];
while(temp > 0) {
info[i][0] = scanner.nextInt();
info[i][1] = scanner.nextInt();
info[i][2] = scanner.nextInt();
i++;
temp--;
}
ScannerInfo scannerInfo = new ScannerInfo(treeRootNum, info);
return scannerInfo;
}
private static TreeNode constructTree(int rootNum, int[][] info) {
cache = new HashMap<>();
if (info == null || info.length == 0 || rootNum == 0) {
return null;
}
for(int i = 0;i < info.length;i++) {
TreeNode cur = getOrPutFromCache(info[i][0]);
TreeNode left = getOrPutFromCache(info[i][1]);
TreeNode right = getOrPutFromCache(info[i][2]);
cur.left = left;
cur.right = right;
}
return cache.get(rootNum);
}
private static TreeNode getOrPutFromCache(int num) {
if (num == 0) {
return null;
}
TreeNode result = cache.get(num);
if (result == null) {
result = new TreeNode(num);
cache.put(num, result);
}
return result;
}
}把t1称为大树,t2称为小树,题目可以转化为在大树,大树的左子树,大树的右子树上寻找小树。
如果小树已经遍历到null,那么说明在大树中找到了小树,此时大树可能为空(完全相同的结构),也可能不为空(小树只是大树的一部分);如果发现大树遍历到了null,那么说明没找到小树,返回false;如果发现两者值不同,那么把大树分别移到左孩子和右孩子重复上述过程,只要大树的左右子树上有一颗找到即可,所以用||连接;如果发现两者值相同,那么就分别校验对应左右位置上的值是否正确,此时必须左右子树都相等方可返回true。

京公网安备 11010502036488号