程序员代码面试指南刷题--第三章.判断t1树中是否有与t2树拓扑结构完全相同的子树

题目描述
给定彼此独立的两棵二叉树,判断 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

输入

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

输出

true

解法一:类似上一题只不过加一个判断条件

import java.io.*;
import java.util.*;
public class Main{
    public static void main(String[] args) throws Exception{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        br.readLine();
        TreeNode r1 = createTree(br);
        br.readLine();
        TreeNode r2 = createTree(br);
        boolean res = judge(r1,r2);
        System.out.println(res);
    }
    public static boolean judge(TreeNode r1,TreeNode r2){
        if(r1==null&&r2==null) return false;
        if(r1==null||r2==null) return false;
        Stack<TreeNode> s = new Stack<>();
        s.push(r1);
        while(!s.isEmpty()){
            TreeNode p = s.pop();
            if(p.val==r2.val){
                if(isChild(p,r2)) return true;                
            }
            if(p.right!=null){
                s.push(p.right);    
            }
            if(p.left!=null){
                s.push(p.left);
            }
        }
        return false;
    }
    public static boolean isChild(TreeNode r1,TreeNode r2){
        //按照r2前序遍历
        Stack<TreeNode> s1 = new Stack<>();
        s1.push(r1);
        Stack<TreeNode> s2 = new Stack<>();
        s2.push(r2);
        while(!s2.isEmpty()){
            TreeNode node1 = s1.pop();
            TreeNode node2 = s2.pop();
            if(node1.val!=node2.val) return false;
            if(node2.right!=null){
                if(node1.right==null) return false;
                s1.push(node1.right);
                s2.push(node2.right);
            }else if(node1.right!=null){
                return false;
            }
            if(node2.left!=null){
                if(node1.left==null) return false;
                s1.push(node1.left);
                s2.push(node2.left);
            }else if(node2.left!=null){
                return false;
            }
        }
        return true;
    }
    //递归建树
    public static TreeNode createTree(BufferedReader br){
        try{
            String[] ss = br.readLine().trim().split(" ");
            int data = Integer.parseInt(ss[0]);
            int left = Integer.parseInt(ss[1]);
            int right = Integer.parseInt(ss[2]);
            TreeNode root = new TreeNode(data);
            if(left!=0){
                root.left = createTree(br);
            }
            if(right!=0){
                root.right = createTree(br);
            }
            return root;
        }catch(Exception e){
            return null;
        }
    }
}
class TreeNode{
    int val;
    TreeNode left;
    TreeNode right;
    public TreeNode(int val){
        this.val = val;
    }
}



解法二:同上递归

import java.io.*;
import java.util.*;
public class Main{
    public static void main(String[] args) throws Exception{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        br.readLine();
        TreeNode r1 = createTree(br);
        br.readLine();
        TreeNode r2 = createTree(br);
        boolean res = judge(r1,r2);
        System.out.println(res);
    }
    public static boolean judge(TreeNode r1,TreeNode r2){
        if(r1==null&&r2==null) return false;
        if(r1==null||r2==null) return false;
        return isChild(r1,r2)||judge(r1.left,r2)||judge(r1.right,r2);
    }
    public static boolean isChild(TreeNode r1,TreeNode r2){
        if(r2==null&&r1==null) return true;
        if(r2==null||r1==null) return false;
        if(r1.val!=r2.val) return false;
        return isChild(r1.left,r2.left)&&isChild(r1.right,r2.right);
    }
    //递归建树
    public static TreeNode createTree(BufferedReader br){
        try{
            String[] ss = br.readLine().trim().split(" ");
            int data = Integer.parseInt(ss[0]);
            int left = Integer.parseInt(ss[1]);
            int right = Integer.parseInt(ss[2]);
            TreeNode root = new TreeNode(data);
            if(left!=0){
                root.left = createTree(br);
            }
            if(right!=0){
                root.right = createTree(br);
            }
            return root;
        }catch(Exception e){
            return null;
        }
    }
}
class TreeNode{
    int val;
    TreeNode left;
    TreeNode right;
    public TreeNode(int val){
        this.val = val;
    }
}



解法二:先序序列化–>字符串匹配

import java.io.*;
import java.util.*;
public class Main{
    public static void main(String[] args) throws Exception{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        br.readLine();
        TreeNode r1 = createTree(br);
        br.readLine();
        TreeNode r2 = createTree(br);
        boolean res = judge(r1,r2);
        System.out.println(res);
    }
    public static boolean judge(TreeNode r1,TreeNode r2){
        String s1 = preOrder(r1);
        String s2 = preOrder(r2);
        //KMP匹配
        return match(s1,s2);
    }
    public static boolean match(String s1,String s2){
        if(s1==null||s2==null||s1.length()<s2.length()||s2.length()<1) return false;
        char[] arr1 = s1.toCharArray();
        char[] arr2 = s2.toCharArray();
        int[] next = getNext(arr2);
        int l1 = 0;
        int l2 = 0;
        while(l1<arr1.length&&l2<arr2.length){
            if(arr1[l1]==arr2[l2]){
                l1++;
                l2++;
            }else if(next[l2]>=0){
                l2 = next[l2];
            }else{
                l1++;
            }                
        }
        return l2==arr2.length?true:false;
    }
    public static int[] getNext(char[] arr){
        if(arr.length==1) return new int[]{-1};
        int[] next = new int[arr.length];
        next[0] = -1;
        next[1] = 0;
        int pos = 2;
        int cn = 0;
        while(pos<arr.length){
            if(arr[pos-1]==arr[cn]){
                next[pos++] = ++cn; 
            }else if(cn==0){
                next[pos++] = 0;
            }else{
                cn = next[cn];
            }
        }
        return next;
    }
    //前序序列化
    public static String preOrder(TreeNode r){
        if(r==null) return "#!";
        String res = r.val+"!";
        res += preOrder(r.left);
        res += preOrder(r.right);
        return res;
    }
    
    //递归建树
    public static TreeNode createTree(BufferedReader br){
        try{
            String[] ss = br.readLine().trim().split(" ");
            int data = Integer.parseInt(ss[0]);
            int left = Integer.parseInt(ss[1]);
            int right = Integer.parseInt(ss[2]);
            TreeNode root = new TreeNode(data);
            if(left!=0){
                root.left = createTree(br);
            }
            if(right!=0){
                root.right = createTree(br);
            }
            return root;
        }catch(Exception e){
            return null;
        }
    }
}
class TreeNode{
    int val;
    TreeNode left;
    TreeNode right;
    public TreeNode(int val){
        this.val = val;
    }
}



发布了189 篇原创文章 · 获赞 8 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_44406146/article/details/105549988