代码如下

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。