package com.interview.tree; import java.util.Deque; import java.util.LinkedList; /** * Check if given pre array sequence will create a binary search tree or not. * * Idea is to keep minimal acceptable value. Any element in pre array should never be less * than minimal acceptable value. Values are popped from stack till they are less than pre[i] * Last popped value becomes new minimally acceptable vaue. * * It does not work for duplicates * * Time complexity - O(n) * https://leetcode.com/problems/verify-preorder-sequence-in-binary-search-tree/ * Reference - http://www.geeksforgeeks.org/check-if-a-given-array-can-represent-preorder-traversal-of-binary-search-tree/ */ public class IsPreOrderArrayBST { public boolean verifyPreorder(int pre[]) { Deque<Integer> deque = new LinkedList<>(); int minAcceptable = Integer.MIN_VALUE; deque.addFirst(pre[0]); for(int i = 1; i < pre.length; i++) { if(pre[i] < minAcceptable) { return false; } while(!deque.isEmpty() && deque.peekFirst() < pre[i]) { minAcceptable = deque.pollFirst(); } deque.addFirst(pre[i]); } return true; } public boolean verifyPreorderConstantSpace(int[] preorder) { int start = 0; int min = Integer.MIN_VALUE; for (int i = 1; i < preorder.length; i++) { if (preorder[i] < min) { return false; } if (preorder[i] > preorder[i - 1]) { int index = binarySearch(preorder, start, i - 1, preorder[i]); min = preorder[index]; start = i; } } return true; } int binarySearch(int[] preorder, int start, int end, int val) { int s = start; int e = end; while (s <= e) { int middle = (s + e)/2; if (preorder[middle] < val && (start == middle || preorder[middle - 1] > val)) { return middle; } else if (preorder[middle] < val) { e = middle - 1; } else { s = middle + 1; } } return -1; } public static void main(String args[]) { IsPreOrderArrayBST isb = new IsPreOrderArrayBST(); int[] input = {10, 3, -1, 4, 13, 11, 12, 10}; System.out.println(isb.verifyPreorder(input)); System.out.println(isb.verifyPreorderConstantSpace(input)); } }