package com.interview.tree; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; /** * http://www.geeksforgeeks.org/check-for-identical-bsts-without-building-the-trees/ * Test cases * Both array should be same size and have exact same elements and first element should be same */ public class IdenticalTrees { private class BigSmall{ int big; int small; } public boolean sameBST(int tree1[], int tree2[]){ return sameBST(tree1,tree2,Integer.MIN_VALUE,Integer.MAX_VALUE,0); } private boolean sameBST(int tree1[],int tree2[],int min,int max,int index){ if(index ==tree1.length){ return true; } int i=0; for(i=0; i < tree2.length; i++){ if(tree2[i] == tree1[index]){ break; } } BigSmall bs1 = nextBigSmall(tree1,index,min,max); BigSmall bs2 = nextBigSmall(tree2,i,min,max); boolean r1= tree1[bs1.big] == tree2[bs2.big] && tree1[bs1.small] == tree2[bs2.small] ; if(r1 == false){ return false; } boolean r2 = true,r3 =true; if(bs1.small != 0){ r2 = sameBST(tree1,tree2,min,tree1[index],bs1.small); } if(bs1.big != 0){ r3 = sameBST(tree1,tree2,tree1[index],max,bs1.big); } return r2 && r3; } private BigSmall nextBigSmall(int[] tree,int index,int min,int max){ BigSmall bs = new BigSmall(); boolean seenBig = false, seenSmall = false; for(int i=index+1; i < tree.length && (!seenBig || !seenSmall); i++){ if(tree[i] > max || tree[i] < min){ continue; } if(!seenBig && tree[i] > tree[index]){ bs.big = i; seenBig = true; } if(!seenSmall && tree[i] < tree[index]){ bs.small = i; seenSmall = true; } } return bs; } /** * Little simpler version of above implementation. Uses more space but atleast its easy to understand. * All it does is makes 2 list one of larger and one of smaller element than root and then passes * them into left and right sides * @param arr1 * @param arr2 * @return */ public boolean sameBST1(int arr1[], int arr2[]){ List<Integer> list1 = new ArrayList<>(); for(int i : arr1){ list1.add(i); } List<Integer> list2 = new ArrayList<>(); for(int i : arr2){ list2.add(i); } return sameBST1(list1, list2); } /** * It might not work for duplicate elements in array. For that you have to store * both index and actual value to differentiate somehow. */ private boolean sameBST1(List<Integer> arr1, List<Integer> arr2){ if(arr1.size() == 0 && arr2.size() == 0){ return true; } if(arr1.size() == 0 || arr2.size() == 0){ return false; } if(arr1.get(0) != arr2.get(0)){ return false; } List<Integer> smaller1 = new ArrayList<Integer>(); List<Integer> larger1= new ArrayList<Integer>(); boolean first = true; for(Integer i : arr1){ if(first){ first = false; continue; } if(i <= arr1.get(0)){ smaller1.add(i); }else{ larger1.add(i); } } first = true; List<Integer> smaller2 = new ArrayList<Integer>(); List<Integer> larger2= new ArrayList<Integer>(); for(Integer i : arr2){ if(first){ first = false; continue; } if(i <= arr2.get(0)){ smaller2.add(i); }else{ larger2.add(i); } } boolean r = compare(smaller1, smaller2) && compare(larger1, larger2); if(!r){ return false; } return sameBST1(smaller1, smaller2) && sameBST1(larger1, larger2); } private boolean compare(List<Integer> l1, List<Integer> l2){ Set<Integer> s = new HashSet<Integer>(); for(Integer i : l1){ s.add(i); } for(Integer i : l2){ if(!s.contains(i)){ return false; } } return true; } public static void main(String args[]){ int tree1[] = {3,-6,-2,11,9,-10,-1,15,10}; int tree2[] = {3,11,9,15,-6,10,-2,-1,-10}; IdenticalTrees it = new IdenticalTrees(); System.out.println(it.sameBST(tree1, tree2)); System.out.println(it.sameBST1(tree1, tree2)); } }