This question was asked in one of the interview : Given two unsorted array, check if it will create the same bst. eg: 2, 1, 4, 0 and 2, 1, 0, 4 will both form same BST.
2
/ \
1 4
/
0
please suggest some good algo.
Set The middle element of the array as root. Recursively do the same for the left half and right half. Get the middle of the left half and make it the left child of the root created in step 1. Get the middle of the right half and make it the right child of the root created in step 1.
Now, the question arises, is Binary Search applicable on unsorted arrays? So, the answer is NO, it is not possible to use or implement Binary Search on unsorted arrays or lists, because, the repeated targeting of the mid element of one half depends on the sorted order of data structure.
Write a SortedMerge() function that takes two lists, each of which is unsorted, and merges the two together into one new list which is in sorted (increasing) order. SortedMerge() should return the new list.
No, binary search needs a sorted array.
All the elements which are greater then the root element should appear in the same order in both the arrays
And of course the very first condition is that both the arrays should contain the same elements but in different order .
Hence this can be solved in linear time.
Pseudocode would be like this:
int GetNextIncresingElement(int[] arr, ref int index, int root)
{
for(int i = index; i< arr.Length; i++)
{
if(arr[i] > root)
{
index = i;
return arr[i];
}
}
return -1;
}
int GetNextDecreasingElement(int[] arr, ref int index, int root)
{
for(int i = index; i< arr.Length; i++)
{
if(arr[i] <= root)
{
index = i;
return arr[i];
}
}
return -1;
}
bool CheckFormsSameBST(int[] arr1, int[] arr2)
{
int index1 = 1;
int index2 = 1;
int num1;
int num2;
int root = arr1[0];
if(root != arr2[0])
return false;
while(true)
{
num1 = GetNextIncresingElement(arr1, ref index1, root);
num2 = GetNextIncresingElement(arr2, ref index2, root);
if(num1 != num2)
return false;
else
{
if(num1 == -1)
break;
}
index1++;
index2++;
}
index1 = 1;
index2 = 1;
while(true)
{
num1 = GetNextDecreasingElement(arr1, ref index1, root);
num2 = GetNextDecreasingElement(arr2, ref index2, root);
if(num1 != num2)
return false;
else
{
if(num1 == -1)
break;
}
index1++;
index2++;
}
return true;
}
I agree with the idea Peter and Algorist described. But I believe the sub-trees of each node (represented by the array less than this node and the array larger than it) need to be examined in this fashion as well. For example, 621407 and 621047 yield the same BST but 624017 does not. The function can be written recursively.
sample code added:
bool sameBST(int * t1, int * t2, int startPos, int endPos) {
int rootPos1, rootPos2;
if (endPos-startPos<0) return true;
if (t1[startPos]!=t2[startPos]) return false;
rootPos1=partition(t1,startPos,endPos,t1[startPos]);
rootPos2=partition(t2,startPos,endPos,t2[startPos]);
if (rootPos1!=rootPos2) return false;
return sameBST(t1,t2,startPos,rootPos1-1) && sameBST(t1,t2,rootPos1+1,endPos);
}
Function partition is the same one you use in quicksort. Apparently, T(n)=2T(n/2)+O(n), which leads to time complexity T(n)=O(nlogn). Because of the recursion, the space complexity is O(logn)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With