Given an array that contains a Post order traversal of a Binary Tree. Check if a possible Binary Tree formed from the postorder traversal is a Binary Search Tree.
For example, a1=[1, 3, 4, 2, 7, 6, 5] is a BST but a2=[1, 3, 4, 6, 7, 2, 5] is not a BST.
5 5 / \ / \ 2 6 4 2 / \ \ / \ 1 4 7 3 7 / / / 3 1 6 (a1) (a2)
In order to be a BST, a binary tree should satisfy that any subtree rooted at node r is greater than all nodes in its left subtree and smaller than nodes in its right subtree. Now, in post order traversal we traverse left subtree first then the right subtree and at last the root. Thus, if the array is a post traversal of a BST, then a[0..n-1] can be divided into two parts a[0..i-1] and a[i, n-2], where
- Each item in left subtree a[0..i-1] is less than a[n-1]
- Each item in right subtree a[i..n-2] is greater than a[n-1]
- Both left subtree a[0..i-1] and right subtree a[i..n-2] are BSTs
So, for the given root a[n-1] we can find the start of a potential right subtree by scanning the array from left to right and check where the element is bigger than root. left side of this point is a left subtree. We also need to do sanity check whether the right subtree contains elements greater than root.
{1, 3, 4, 2, 7, 6, 5} 5 ^ / \ / \ 2 6 {1, 3, 4, 2} {7,6} / \ \ ^ ^ 1 4 7 / \ \ / {1} {3,4} {7} 3 ^ / {3}
Below is the implementation of this idea which runs in O(ngln) time in average case where the tree is a balanced binary tree and O(n) space. The worst case complexity however is O(n^2) in case of a tall binary tree such as a=[1,2,3,4,5]
5 / 4 / 3 / 2 / 1
public static boolean isBSTPostOrder(int[] a, int p, int q){ int n = q-p+1;; //base case always true for 1 element if(n < 2){ return true; } //partition into left subtree a[p..right-1] and right subtree a[right..q-1] int right = p; while(a[right] < a[q]) right++; //check validity of right subtree int i = right; while(i < q && a[i] > a[q]) i++; if(i < q){ return false; } return isBSTPostOrder(a, p, right-1) && isBSTPostOrder(a, right, q-1); }