[Naive approach] First Greater Element - O(n ^ 2) Time and O(n) Space
The idea is to treat the first element as the root, find the first greater element which separates the left and right subtrees, and verify that all elements in the right subtree are greater than the root. Recursively apply the same check to the left and right subarrays.
For example in [40, 30, 35, 80, 100], 40 is the first element, so we make it root. Now we look for the first element greater than 40, we find 80. So we know the structure of BST is as follows:
C++
#include<bits/stdc++.h>usingnamespacestd;boolcheck(vector<int>&arr,intl,intr){// If subtree has 0 or 1 nodeif(l>=r)returntrue;intj=l+1;// Find first element greater than rootwhile(j<=r&&arr[j]<arr[l])j++;// Check whether all elements in right subtree// are greater than rootfor(intk=j;k<=r;k++){if(arr[k]<arr[l])returnfalse;}// Recursively check left and right subtreesreturncheck(arr,l+1,j-1)&&check(arr,j,r);}boolcanRepresentBST(vector<int>&arr){returncheck(arr,0,arr.size()-1);}// Driver Codeintmain(){vector<int>arr={40,30,35,80,100};if(canRepresentBST(arr))cout<<"true\n";elsecout<<"false\n";return0;}
defcheck(arr,l,r):# If subtree has 0 or 1 nodeifl>=r:returnTruej=l+1# Find first element greater than rootwhilej<=randarr[j]<arr[l]:j+=1# Check whether all elements in right subtree# are greater than rootforkinrange(j,r+1):ifarr[k]<arr[l]:returnFalse# Recursively check left and right subtreesreturncheck(arr,l+1,j-1)andcheck(arr,j,r)defcanRepresentBST(arr):returncheck(arr,0,len(arr)-1)# Driver Codeif__name__=="__main__":arr=[40,30,35,80,100]ifcanRepresentBST(arr):print("true")else:print("false")
C#
usingSystem;publicclassGFG{staticboolCheck(int[]arr,intl,intr){// If subtree has 0 or 1 nodeif(l>=r)returntrue;intj=l+1;// Find first element greater than rootwhile(j<=r&&arr[j]<arr[l])j++;// Check whether all elements in right subtree// are greater than rootfor(intk=j;k<=r;k++){if(arr[k]<arr[l])returnfalse;}// Recursively check left and right subtreesreturnCheck(arr,l+1,j-1)&&Check(arr,j,r);}staticboolCanRepresentBST(int[]arr){returnCheck(arr,0,arr.Length-1);}// Driver CodestaticvoidMain(){int[]arr={40,30,35,80,100};if(CanRepresentBST(arr))Console.WriteLine("true");elseConsole.WriteLine("false");}}
JavaScript
functioncheck(arr,l,r){// If subtree has 0 or 1 nodeif(l>=r)returntrue;letj=l+1;// Find first element greater than rootwhile(j<=r&&arr[j]<arr[l])j++;// Check whether all elements in right subtree// are greater than rootfor(letk=j;k<=r;k++){if(arr[k]<arr[l])returnfalse;}// Recursively check left and right subtreesreturncheck(arr,l+1,j-1)&&check(arr,j,r);}functioncanRepresentBST(arr){returncheck(arr,0,arr.length-1);}// Driver Codeconstarr=[40,30,35,80,100];if(canRepresentBST(arr))console.log('true');elseconsole.log('false');
Output
true
[Expected Approach - 1] Using Stack - O(n) Time and O(n) Space
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.
Let us Understand with example: Input: arr[] = [40, 30, 35, 80, 100]
Start with root = -â and an empty stack. Push 40 -> Stack = [40].
30 is greater than root and smaller than stack top, so push it -> Stack = [40, 30].
35 is greater than stack top 30, so pop 30 and update root = 30. Then push 35 -> Stack = [40, 35].
80 is greater than stack top, so keep popping: 35 -> root = 35, 40 -> root = 40. Push 80 -> Stack = [80].
100 is greater than 80, so pop 80 and update root = 80. Push 100. No element was found smaller than the current root, so the preorder traversal is valid and the answer is true.
C++
#include<bits/stdc++.h>usingnamespacestd;boolcanRepresentBST(vector<int>&arr){stack<int>s;// Initialize current root as minimum possible// valueintroot=INT_MIN;for(inti=0;i<arr.size();i++){// If we find a node who is on right side// and smaller than root, return falseif(arr[i]<root)returnfalse;// If pre[i] is in right subtree of stack top,// Keep removing items smaller than pre[i]// and make the last removed item as new// root.while(!s.empty()&&s.top()<arr[i]){root=s.top();s.pop();}// At this point either stack is empty or// pre[i] is smaller than root, push pre[i]s.push(arr[i]);}returntrue;}intmain(){vector<int>arr={40,30,35,80,100};if(canRepresentBST(arr))cout<<"true\n";elsecout<<"false\n";return0;}
Java
importjava.util.*;publicclassGFG{publicstaticbooleancanRepresentBST(List<Integer>arr){Stack<Integer>s=newStack<>();// Initialize current root as minimum possible// valueintroot=Integer.MIN_VALUE;for(inti=0;i<arr.size();i++){// If we find a node who is on right side// and smaller than root, return falseif(arr.get(i)<root)returnfalse;// If arr[i] is in right subtree of stack top,// Keep removing items smaller than arr[i]// and make the last removed item as new// root.while(!s.isEmpty()&&s.peek()<arr.get(i)){root=s.pop();}// At this point either stack is empty or// arr[i] is smaller than root, push arr[i]s.push(arr.get(i));}returntrue;}publicstaticvoidmain(String[]args){List<Integer>arr=Arrays.asList(40,30,35,80,100);if(canRepresentBST(arr))System.out.println("true");elseSystem.out.println("false");}}
Python
defcanRepresentBST(arr):stack=[]# Initialize current root as minimum possible# valueroot=float('-inf')foriinrange(len(arr)):# If we find a node who is on right side# and smaller than root, return falseifarr[i]<root:returnFalse# If arr[i] is in right subtree of stack top,# Keep removing items smaller than arr[i]# and make the last removed item as new# root.whilestackandstack[-1]<arr[i]:root=stack.pop()# At this point either stack is empty or# arr[i] is smaller than root, push arr[i]stack.append(arr[i])returnTrue# Driver Codeif__name__=="__main__":arr=[40,30,35,80,100]ifcanRepresentBST(arr):print("true")else:print("false")
C#
usingSystem;usingSystem.Collections.Generic;publicclassGFG{publicstaticboolcanRepresentBST(List<int>arr){Stack<int>s=newStack<int>();// Initialize current root as minimum possible// valueintroot=int.MinValue;for(inti=0;i<arr.Count;i++){// If we find a node who is on right side// and smaller than root, return falseif(arr[i]<root)returnfalse;// If arr[i] is in right subtree of stack top,// Keep removing items smaller than arr[i]// and make the last removed item as new// root.while(s.Count>0&&s.Peek()<arr[i]){root=s.Pop();}// At this point either stack is empty or// arr[i] is smaller than root, push arr[i]s.Push(arr[i]);}returntrue;}publicstaticvoidMain(){List<int>arr=newList<int>{40,30,35,80,100};if(canRepresentBST(arr))Console.WriteLine("true");elseConsole.WriteLine("false");}}
[Expected Approach - 2] Pass Range in Recursion - O(n) Time and O(n) Space
The trick is to set a range {min .. max} for every node. We initialize range as [-inf, +inf]. We begin with the first element of the preorder traversal, Now moving forward, we set the range as [-inf, key] for left subtree and [key, inf] for right subtree. We mainly maintain a shared variable in function calls preIndex and increment it if we find the node in range. If reach end, then the tree is BST.
Follow the below steps to solve the problem:
Initialize the range as {-inf , +inf}
The first node will definitely be in range, so create a root node.Â
To process the left subtree, set the range as {-inf, root.key} and for right subtree as [root.key, +inf]
Let us Understand with example: Input: arr[] = [40, 30, 35, 80, 100]
Start with range (-â, +â). 40 lies in the range, so process it as the root and move to the next element.
For the left subtree of 40, range becomes (-â, 40). 30 and then 35 fit within valid ranges and are processed.
After the left subtree is completed, move to the right subtree of 40 with range (40, +â).
80 and then 100 satisfy their respective valid ranges and are processed.
All elements are consumed (preIndex == n), so the array represents a valid BST preorder traversal.
C++
#include<bits/stdc++.h>usingnamespacestd;voidbuildBSThelper(int&preIndex,intn,vector<int>&pre,intmin,intmax){// If we have processed all elements, returnif(preIndex>=n)return;// If the current element lies between min and max,// it can be part of the BSTif(min<=pre[preIndex]&&pre[preIndex]<=max){// Treat the current element as the root of// this subtreeintrootData=pre[preIndex];preIndex++;buildBSThelper(preIndex,n,pre,min,rootData);buildBSThelper(preIndex,n,pre,rootData,max);}}boolcanRepresentBST(vector<int>&arr){// Set the initial min and max valuesintmin=INT_MIN,max=INT_MAX;// Start from the first element in// the arrayintpreIndex=0;intn=arr.size();buildBSThelper(preIndex,n,arr,min,max);// If all elements are processed, it means the// array represents a valid BSTreturnpreIndex==n;}// Driver Codeintmain(){vector<int>arr={40,30,35,80,100};if(canRepresentBST(arr))cout<<"true\n";elsecout<<"false\n";return0;}
Java
importjava.util.*;publicclassGFG{staticvoidbuildBSThelper(int[]preIndex,intn,List<Integer>pre,intmin,intmax){// If we have processed all elements, returnif(preIndex[0]>=n)return;// If the current element lies between min and max,// it can be part of the BSTif(min<=pre.get(preIndex[0])&&pre.get(preIndex[0])<=max){// Treat the current element as the root of// this subtreeintrootData=pre.get(preIndex[0]);preIndex[0]++;buildBSThelper(preIndex,n,pre,min,rootData);buildBSThelper(preIndex,n,pre,rootData,max);}}staticbooleancanRepresentBST(List<Integer>arr){// Set the initial min and max valuesintmin=Integer.MIN_VALUE;intmax=Integer.MAX_VALUE;// Start from the first element in// the arrayint[]preIndex={0};intn=arr.size();buildBSThelper(preIndex,n,arr,min,max);// If all elements are processed, it means the// array represents a valid BSTreturnpreIndex[0]==n;}// Driver Codepublicstaticvoidmain(String[]args){List<Integer>arr=Arrays.asList(40,30,35,80,100);if(canRepresentBST(arr))System.out.println("true");elseSystem.out.println("false");}}
Python
defbuildBSThelper(preIndex,n,pre,minVal,maxVal):# If we have processed all elements, returnifpreIndex[0]>=n:return# If the current element lies between min and max,# it can be part of the BSTifminVal<=pre[preIndex[0]]<=maxVal:# Treat the current element as the root of# this subtreerootData=pre[preIndex[0]]preIndex[0]+=1buildBSThelper(preIndex,n,pre,minVal,rootData)buildBSThelper(preIndex,n,pre,rootData,maxVal)defcanRepresentBST(arr):# Set the initial min and max valuesminVal=float('-inf')maxVal=float('inf')# Start from the first element in# the arraypreIndex=[0]n=len(arr)buildBSThelper(preIndex,n,arr,minVal,maxVal)# If all elements are processed, it means the# array represents a valid BSTreturnpreIndex[0]==n# Driver Codeif__name__=="__main__":arr=[40,30,35,80,100]ifcanRepresentBST(arr):print("true")else:print("false")
C#
usingSystem;usingSystem.Collections.Generic;publicclassGFG{staticvoidbuildBSThelper(refintpreIndex,intn,List<int>pre,intmin,intmax){// If we have processed all elements, returnif(preIndex>=n)return;// If the current element lies between min and max,// it can be part of the BSTif(min<=pre[preIndex]&&pre[preIndex]<=max){// Treat the current element as the root of// this subtreeintrootData=pre[preIndex];preIndex++;buildBSThelper(refpreIndex,n,pre,min,rootData);buildBSThelper(refpreIndex,n,pre,rootData,max);}}staticboolcanRepresentBST(List<int>arr){// Set the initial min and max valuesintmin=int.MinValue;intmax=int.MaxValue;// Start from the first element in// the arrayintpreIndex=0;intn=arr.Count;buildBSThelper(refpreIndex,n,arr,min,max);// If all elements are processed, it means the// array represents a valid BSTreturnpreIndex==n;}// Driver CodepublicstaticvoidMain(){List<int>arr=newList<int>{40,30,35,80,100};if(canRepresentBST(arr))Console.WriteLine("true");elseConsole.WriteLine("false");}}
JavaScript
functionbuildBSThelper(preIndex,n,pre,min,max){// If we have processed all elements, returnif(preIndex.index>=n)return;// If the current element lies between min and max,// it can be part of the BSTif(min<=pre[preIndex.index]&&pre[preIndex.index]<=max){// Treat the current element as the root of// this subtreeletrootData=pre[preIndex.index];preIndex.index++;buildBSThelper(preIndex,n,pre,min,rootData);buildBSThelper(preIndex,n,pre,rootData,max);}}functioncanRepresentBST(arr){// Set the initial min and max valuesletmin=-Infinity,max=Infinity;// Start from the first element in// the arrayletpreIndex={index:0};letn=arr.length;buildBSThelper(preIndex,n,arr,min,max);// If all elements are processed, it means the// array represents a valid BSTreturnpreIndex.index===n;}// Driver Codeletarr=[40,30,35,80,100];if(canRepresentBST(arr))console.log("true");elseconsole.log("false");