Given an array of numbers, return true if given array can represent preorder traversal of a Binary Search Tree, else return false. Expected time complexity is O(n).
Examples:
Input: pre[] = {2, 4, 3}
Output: true
Given array can represent preorder traversal
of below tree
2
\
4
/
3
Input: pre[] = {2, 4, 1}
Output: false
Given array cannot represent preorder traversal
of a Binary Search Tree.
Input: pre[] = {40, 30, 35, 80, 100}
Output: true
Given array can represent preorder traversal
of below tree
40
/ \
30 80
\ \
35 100
Input: pre[] = {40, 30, 35, 20, 80, 100}
Output: false
Given array cannot represent preorder traversal
of a Binary Search Tree.
A Simple Solution is to do following for every node pre[i] starting from first one.
1) Find the first greater value on right side of current node.
Let the index of this node be j. Return true if following
conditions hold. Else return false
(i) All values after the above found greater value are
greater than current node.
(ii) Recursive calls for the subarrays pre[i+1..j-1] and
pre[j+1..n-1] also return true.
Time Complexity of the above solution is O(n2)
An Efficient Solution can solve this problem in O(n) time. The idea is to use a stack. This problem is similar to Next (or closest) Greater Element problem. Here we find the next greater element and after finding next greater, if we find a smaller element, then return false.
1) Create an empty stack.
2) Initialize root as INT_MIN.
3) Do following for every element pre[i]
a) If pre[i] is smaller than current root, return false.
b) Keep removing elements from stack while pre[i] is greater
then stack top. Make the last removed item as new root (to
be compared next).
At this point, pre[i] is greater than the removed root
(That is why if we see a smaller element in step a), we
return false)
c) push pre[i] to stack (All elements in stack are in decreasing
order)
Below is the implementation of above idea.
C++
#include<bits/stdc++.h>
using namespace std;
bool canRepresentBST( int pre[], int n)
{
stack< int > s;
int root = INT_MIN;
for ( int i=0; i<n; i++)
{
if (pre[i] < root)
return false ;
while (!s.empty() && s.top()<pre[i])
{
root = s.top();
s.pop();
}
s.push(pre[i]);
}
return true ;
}
int main()
{
int pre1[] = {40, 30, 35, 80, 100};
int n = sizeof (pre1)/ sizeof (pre1[0]);
canRepresentBST(pre1, n)? cout << "true\n" :
cout << "false\n" ;
int pre2[] = {40, 30, 35, 20, 80, 100};
n = sizeof (pre2)/ sizeof (pre2[0]);
canRepresentBST(pre2, n)? cout << "true\n" :
cout << "false\n" ;
return 0;
}
|
Java
import java.util.Stack;
class BinarySearchTree {
boolean canRepresentBST( int pre[], int n) {
Stack<Integer> s = new Stack<Integer>();
int root = Integer.MIN_VALUE;
for ( int i = 0 ; i < n; i++) {
if (pre[i] < root) {
return false ;
}
while (!s.empty() && s.peek() < pre[i]) {
root = s.peek();
s.pop();
}
s.push(pre[i]);
}
return true ;
}
public static void main(String args[]) {
BinarySearchTree bst = new BinarySearchTree();
int [] pre1 = new int []{ 40 , 30 , 35 , 80 , 100 };
int n = pre1.length;
if (bst.canRepresentBST(pre1, n) == true ) {
System.out.println( "true" );
} else {
System.out.println( "false" );
}
int [] pre2 = new int []{ 40 , 30 , 35 , 20 , 80 , 100 };
int n1 = pre2.length;
if (bst.canRepresentBST(pre2, n) == true ) {
System.out.println( "true" );
} else {
System.out.println( "false" );
}
}
}
|
Python3
INT_MIN = - 2 * * 32
def canRepresentBST(pre):
s = []
root = INT_MIN
for value in pre:
if value < root :
return False
while ( len (s) > 0 and s[ - 1 ] < value) :
root = s.pop()
s.append(value)
return True
pre1 = [ 40 , 30 , 35 , 80 , 100 ]
print ( "true" if canRepresentBST(pre1) = = True else "false" )
pre2 = [ 40 , 30 , 35 , 20 , 80 , 100 ]
print ( "true" if canRepresentBST(pre2) = = True else "false" )
|
C#
using System;
using System.Collections.Generic;
class GFG
{
public virtual bool canRepresentBST( int [] pre, int n)
{
Stack< int > s = new Stack< int >();
int root = int .MinValue;
for ( int i = 0; i < n; i++)
{
if (pre[i] < root)
{
return false ;
}
while (s.Count > 0 && s.Peek() < pre[i])
{
root = s.Peek();
s.Pop();
}
s.Push(pre[i]);
}
return true ;
}
public static void Main( string [] args)
{
GFG bst = new GFG();
int [] pre1 = new int []{40, 30, 35, 80, 100};
int n = pre1.Length;
if (bst.canRepresentBST(pre1, n) == true )
{
Console.WriteLine( "true" );
}
else
{
Console.WriteLine( "false" );
}
int [] pre2 = new int []{40, 30, 35, 20, 80, 100};
int n1 = pre2.Length;
if (bst.canRepresentBST(pre2, n) == true )
{
Console.WriteLine( "true" );
}
else
{
Console.WriteLine( "false" );
}
}
}
|
Javascript
<script>
function canRepresentBST(pre, n)
{
var s = [];
var root = -1000000000;
for ( var i = 0; i < n; i++)
{
if (pre[i] < root)
return false ;
while (s.length != 0 && s[s.length - 1] < pre[i])
{
root = s[s.length - 1];
s.pop();
}
s.push(pre[i]);
}
return true ;
}
var pre1 = [ 40, 30, 35, 80, 100 ];
var n = pre1.length;
canRepresentBST(pre1, n) ? document.write( "true<br>" ):
document.write( "false<br>" );
var pre2 = [ 40, 30, 35, 20, 80, 100 ];
n = pre2.length;
canRepresentBST(pre2, n) ? document.write( "true" ):
document.write( "false" );
</script>
|
Time Complexity: O(n)
Auxiliary Space: O(n)
Another approach:
We can check if the given preorder traversal is valid or not for a BST without using stack. The idea is to use the similar concept of “Building a BST using narrowing bound algorithm”. We will recursively visit all nodes, but we will not build the nodes. In the end, if the complete array is not traversed, then that means that array can not represent the preorder traversal of any binary tree.
Below is the implementation of the above idea:
C++
#include <bits/stdc++.h>
using namespace std;
void buildBST_helper( int & preIndex, int n, int pre[],
int min, int max)
{
if (preIndex >= n)
return ;
if (min <= pre[preIndex] && pre[preIndex] <= max) {
int rootData = pre[preIndex];
preIndex++;
buildBST_helper(preIndex, n, pre, min, rootData);
buildBST_helper(preIndex, n, pre, rootData, max);
}
}
bool canRepresentBST( int arr[], int N)
{
int min = INT_MIN, max = INT_MAX;
int preIndex = 0;
buildBST_helper(preIndex, N, arr, min, max);
return preIndex == N;
}
int main()
{
int preorder1[] = { 2, 4, 3 };
int n1 = sizeof (preorder1) / sizeof (preorder1[0]);
if (canRepresentBST(preorder1, n1))
cout << "\npreorder1 can represent BST" ;
else
cout << "\npreorder1 can not represent BST :(" ;
int preorder2[] = { 5, 3, 4, 1, 6, 10 };
int n2 = sizeof (preorder2) / sizeof (preorder2[0]);
if (canRepresentBST(preorder2, n2))
cout << "\npreorder2 can represent BST" ;
else
cout << "\npreorder2 can not represent BST :(" ;
int preorder3[] = { 5, 3, 4, 8, 6, 10 };
int n3 = sizeof (preorder3) / sizeof (preorder3[0]);
if (canRepresentBST(preorder3, n3))
cout << "\npreorder3 can represent BST" ;
else
cout << "\npreorder3 can not represent BST :(" ;
return 0;
}
|
Java
public class Main
{
static int preIndex = 0 ;
static void buildBST_helper( int n, int [] pre, int min, int max)
{
if (preIndex >= n)
return ;
if (min <= pre[preIndex] && pre[preIndex] <= max) {
int rootData = pre[preIndex];
preIndex++;
buildBST_helper(n, pre, min, rootData);
buildBST_helper(n, pre, rootData, max);
}
}
static boolean canRepresentBST( int [] arr, int N)
{
int min = Integer.MIN_VALUE, max = Integer.MAX_VALUE;
buildBST_helper(N, arr, min, max);
return preIndex == N;
}
public static void main(String[] args) {
int [] preorder1 = { 2 , 4 , 3 };
int n1 = preorder1.length;
System.out.println();
if (canRepresentBST(preorder1, n1))
System.out.print( "preorder1 can represent BST" );
else
System.out.print( "preorder1 can not represent BST :(" );
int [] preorder2 = { 5 , 3 , 4 , 1 , 6 , 10 };
int n2 = preorder2.length;
System.out.println();
if (!canRepresentBST(preorder2, n2))
System.out.print( "preorder2 can represent BST" );
else
System.out.print( "preorder2 can not represent BST :(" );
int [] preorder3 = { 5 , 3 , 4 , 8 , 6 , 10 };
int n3 = preorder3.length;
System.out.println();
if (canRepresentBST(preorder3, n3))
System.out.print( "preorder3 can represent BST" );
else
System.out.print( "preorder3 can not represent BST :(" );
}
}
|
Python3
import sys
preIndex = 0
def buildBST_helper(n, pre, Min , Max ):
global preIndex
if (preIndex > = n):
return
if ( Min < = pre[preIndex] and pre[preIndex] < = Max ):
rootData = pre[preIndex]
preIndex + = 1
buildBST_helper(n, pre, Min , rootData)
buildBST_helper(n, pre, rootData, Max )
def canRepresentBST(arr, N):
global preIndex
Min , Max = sys.maxsize, - sys.maxsize
buildBST_helper(N, arr, Min , Max )
if preIndex = = N:
return True
return False
preorder1 = [ 2 , 4 , 3 ]
n1 = len (preorder1)
if ( not canRepresentBST(preorder1, n1)):
print ( "preorder1 can represent BST" );
else :
print ( "preorder1 can not represent BST :(" )
preorder2 = [ 5 , 3 , 4 , 1 , 6 , 10 ]
n2 = len (preorder2)
if (canRepresentBST(preorder2, n2)):
print ( "preorder2 can represent BST" )
else :
print ( "preorder2 can not represent BST :(" )
preorder3 = [ 5 , 3 , 4 , 8 , 6 , 10 ]
n3 = len (preorder3)
if ( not canRepresentBST(preorder3, n3)):
print ( "preorder3 can represent BST" )
else :
print ( "preorder3 can not represent BST :(" )
|
C#
using System;
class GFG {
static int preIndex = 0;
static void buildBST_helper( int n, int [] pre, int min, int max)
{
if (preIndex >= n)
return ;
if (min <= pre[preIndex] && pre[preIndex] <= max) {
int rootData = pre[preIndex];
preIndex++;
buildBST_helper(n, pre, min, rootData);
buildBST_helper(n, pre, rootData, max);
}
}
static bool canRepresentBST( int [] arr, int N)
{
int min = Int32.MinValue, max = Int32.MaxValue;
buildBST_helper(N, arr, min, max);
return preIndex == N;
}
static void Main() {
int [] preorder1 = { 2, 4, 3 };
int n1 = preorder1.Length;
Console.WriteLine();
if (canRepresentBST(preorder1, n1))
Console.Write( "preorder1 can represent BST" );
else
Console.Write( "preorder1 can not represent BST :(" );
int [] preorder2 = { 5, 3, 4, 1, 6, 10 };
int n2 = preorder2.Length;
Console.WriteLine();
if (!canRepresentBST(preorder2, n2))
Console.Write( "preorder2 can represent BST" );
else
Console.Write( "preorder2 can not represent BST :(" );
int [] preorder3 = { 5, 3, 4, 8, 6, 10 };
int n3 = preorder3.Length;
Console.WriteLine();
if (canRepresentBST(preorder3, n3))
Console.Write( "preorder3 can represent BST" );
else
Console.Write( "preorder3 can not represent BST :(" );
}
}
|
Javascript
<script>
let preIndex = 0;
function buildBST_helper(n, pre, min, max)
{
if (preIndex >= n)
return ;
if (min <= pre[preIndex] && pre[preIndex] <= max) {
let rootData = pre[preIndex];
preIndex++;
buildBST_helper(n, pre, min, rootData);
buildBST_helper(n, pre, rootData, max);
}
}
function canRepresentBST(arr, N)
{
let min = Number.MIN_VALUE, max = Number.MAX_VALUE;
buildBST_helper(N, arr, min, max);
return preIndex == N;
}
let preorder1 = [ 2, 4, 3 ];
let n1 = preorder1.length;
if (canRepresentBST(preorder1, n1))
document.write( "</br>" + "preorder1 can represent BST" );
else
document.write( "</br>" + "preorder1 can not represent BST :(" );
let preorder2 = [ 5, 3, 4, 1, 6, 10 ];
let n2 = preorder2.length;
if (!canRepresentBST(preorder2, n2))
document.write( "</br>" + "preorder2 can represent BST" );
else
document.write( "</br>" + "preorder2 can not represent BST :(" );
let preorder3 = [ 5, 3, 4, 8, 6, 10 ];
let n3 = preorder3.length;
if (canRepresentBST(preorder3, n3))
document.write( "</br>" + "preorder3 can represent BST" );
else
document.write( "</br>" + "preorder3 can not represent BST :(" );
</script>
|
Output
preorder1 can represent BST
preorder2 can not represent BST :(
preorder3 can represent BST
Time complexity: O(N)
Auxiliary Space: O(height of the possible binary tree)
Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!
Last Updated :
12 Oct, 2022
Like Article
Save Article