首页 > 试题广场 >

判断t1树是否包含t2树全部的拓扑结构

[编程题]判断t1树是否包含t2树全部的拓扑结构
  • 热度指数:1104 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
给定彼此独立的两棵二叉树,判断 t1 树是否包含 t2 树全部的拓扑结构。
设 t1 树的边集为 E1,t2 树的边集为 E2,若 E2 是 E1 的子集,则表示 t1 树包含 t2 树全部的拓扑结构。

输入描述:
第一行输入两个整数 n 和 root,n 表示二叉树 t1 的总节点个数,root 表示二叉树 t1 的根节点。

以下 n 行每行三个整数 fa,lch,rch,表示 fa 的左儿子为 lch,右儿子为 rch。(如果 lch 为 0 则表示 fa 没有左儿子,rch同理)

第 n+2 行输入两个整数 m 和 root,n 表示二叉树 t2 的总节点个数,root 表示二叉树 t2 的根节点。

以下 m 行每行三个整数 fa,lch,rch,表示 fa 的左儿子为 lch,右儿子为 rch。(如果 lch 为 0 则表示 fa 没有左儿子,rch同理)


输出描述:
如果 t1 树包含 t2 树全部的拓扑结构,则输出 "true",否则输出 "false"。
示例1

输入

10 1
1 2 3
2 4 5
4 8 9
8 0 0
9 0 0
5 10 0
10 0 0
3 6 7
6 0 0
7 0 0
4 2
2 4 5
5 0 0
4 8 0
8 0 0

输出

true

备注:

这个题比判断子树那个更简单一些:
  1. 只有在B树节点全部检查完,无跟A树节点有不相等的情况才返回true;
  2. 如果B树节点还没检查完A树就没有节点了,说明A树剩下的规模已经不足以囊括B树的拓扑结构,返回false;
  3. A树和B树节点值相等,继续检查下面的节点值;
  4. A树和B树节点值不相等,检查B树拓扑结构是否在A树的子树之中。
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.HashMap;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        // 构建树A
        String[] params = br.readLine().split(" ");
        int n = Integer.parseInt(params[0]);
        TreeNode treeA = new TreeNode(Integer.parseInt(params[1]));
        HashMap<Integer, TreeNode> map = new HashMap<>();
        map.put(treeA.val, treeA);
        for(int i = 0; i < n; i++){
            params = br.readLine().split(" ");
            int val = Integer.parseInt(params[0]);
            int leftVal = Integer.parseInt(params[1]);
            int rightVal = Integer.parseInt(params[2]);
            TreeNode node = map.get(val);
            if(leftVal != 0) {
                node.left = new TreeNode(leftVal);
                map.put(leftVal, node.left);
            }
            if(rightVal != 0) {
                node.right = new TreeNode(rightVal);
                map.put(rightVal, node.right);
            }
        }
        // 构建树B
        params = br.readLine().split(" ");
        int m = Integer.parseInt(params[0]);
        TreeNode treeB = new TreeNode(Integer.parseInt(params[1]));
        map.clear();
        map.put(treeB.val, treeB);
        for(int i = 0; i < m; i++){
            params = br.readLine().split(" ");
            int val = Integer.parseInt(params[0]);
            int leftVal = Integer.parseInt(params[1]);
            int rightVal = Integer.parseInt(params[2]);
            TreeNode node = map.get(val);
            if(leftVal != 0) {
                node.left = new TreeNode(leftVal);
                map.put(leftVal, node.left);
            }
            if(rightVal != 0) {
                node.right = new TreeNode(rightVal);
                map.put(rightVal, node.right);
            }
        }
        System.out.println(isSubTopology(treeA, treeB));
    }
    
    private static boolean isSubTopology(TreeNode treeA, TreeNode treeB) {
        if(treeB == null) return true;      // B树节点检查完了返回true
        if(treeA == null) return false;     // B树节点没检查完A树就没节点了返回false
        if(treeA.val == treeB.val){
            // 节点值相等就继续检查下面的节点
            return isSubTopology(treeA.left, treeB.left) && isSubTopology(treeA.right, treeB.right);
        }else{
            // 不相等就检查B树的拓扑结构是不是在A树的子树中
            return isSubTopology(treeA.left, treeB) || isSubTopology(treeA.right, treeB);
        }
    }
}

class TreeNode {
    public int val;
    public TreeNode left;
    public TreeNode right;
    public TreeNode(int val) {
        this.val = val;
    }
}

发表于 2021-12-04 10:05:40 回复(0)