cGiven two arrays pre[] and in[] representing the preorder and inorder traversal of the binary tree, the task is to check if the given traversals are valid for any binary tree or not without building the tree. If it is possible, then print Yes. Otherwise, print No.
Examples:
Input: pre[] = {1, 2, 4, 5, 7, 3, 6, 8}, in[] = {4, 2, 5, 7, 1, 6, 8, 3} Output: Yes Explanation: Both traversals are valid for the following binary tree: 1 / \ 2 3 / \ / 4 5 6 \ \ 7 8
Input: pre[] = {1, 2, 69, 5, 7, 3, 6, 8}, in[] = {4, 2, 5, 7, 1, 6, 8, 3} Output: No
Approach: The idea is to use similar technique to build the binary tree from inorder and preorder traversals, except that not to build the tree, rather to check if the current inorder traversal of that tree(subtree) and the current preorder Index is valid or not in each recursive call or not.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
bool checkInorderPreorderUtil(
int inStart, int inEnd,
int & preIndex, int preorder[],
unordered_map< int , int >& inorderIndexMap)
{
if (inStart > inEnd)
return true ;
int rootData = preorder[preIndex];
preIndex++;
if (inorderIndexMap.find(rootData)
== inorderIndexMap.end())
return false ;
int inorderIndex = inorderIndexMap[rootData];
if (!(inStart <= inorderIndex
&& inorderIndex <= inEnd))
return false ;
int leftInorderStart = inStart;
int leftInorderEnd = inorderIndex - 1;
int rightInorderStart = inorderIndex + 1;
int rightInorderEnd = inEnd;
if (!checkInorderPreorderUtil(
leftInorderStart, leftInorderEnd,
preIndex, preorder, inorderIndexMap))
return false ;
else
return checkInorderPreorderUtil(
rightInorderStart, rightInorderEnd,
preIndex, preorder, inorderIndexMap);
}
string checkInorderPreorder(
int pre[], int in[], int n)
{
unordered_map< int , int > inorderIndexMap;
for ( int i = 0; i < n; i++)
inorderIndexMap[in[i]] = i;
int preIndex = 0;
if (checkInorderPreorderUtil(
0, n - 1, preIndex,
pre, inorderIndexMap)) {
return "Yes" ;
}
else {
return "No" ;
}
}
int main()
{
int pre[] = { 1, 2, 4, 5, 7, 3, 6, 8 };
int in[] = { 4, 2, 5, 7, 1, 6, 8, 3 };
int N = sizeof (pre) / sizeof (pre[0]);
cout << checkInorderPreorder(pre, in, N);
return 0;
}
|
Java
import java.util.*;
class GFG
{
static int preIndex;
static HashMap<Integer,Integer> inorderIndexMap = new HashMap<Integer,Integer>();
static boolean checkInorderPreorderUtil(
int inStart, int inEnd,
int preorder[])
{
if (inStart > inEnd)
return true ;
int rootData = preorder[preIndex];
preIndex++;
if (!inorderIndexMap.containsKey(rootData))
return false ;
int inorderIndex = inorderIndexMap.get(rootData);
if (!(inStart <= inorderIndex
&& inorderIndex <= inEnd))
return false ;
int leftInorderStart = inStart;
int leftInorderEnd = inorderIndex - 1 ;
int rightInorderStart = inorderIndex + 1 ;
int rightInorderEnd = inEnd;
if (!checkInorderPreorderUtil(
leftInorderStart, leftInorderEnd,preorder))
return false ;
else
return checkInorderPreorderUtil(
rightInorderStart, rightInorderEnd,
preorder);
}
static String checkInorderPreorder(
int pre[], int in[], int n)
{
for ( int i = 0 ; i < n; i++)
inorderIndexMap.put(in[i], i);
preIndex = 0 ;
if (checkInorderPreorderUtil(
0 , n - 1 ,
pre)) {
return "Yes" ;
}
else {
return "No" ;
}
}
public static void main(String[] args)
{
int pre[] = { 1 , 2 , 4 , 5 , 7 , 3 , 6 , 8 };
int in[] = { 4 , 2 , 5 , 7 , 1 , 6 , 8 , 3 };
int N = pre.length;
System.out.print(checkInorderPreorder(pre, in, N));
}
}
|
Python3
def checkInorderPreorderUtil(inStart, inEnd, preIndex, preorder, inorderIndexMap):
if (inStart > inEnd):
return True
rootData = preorder[preIndex]
preIndex + = 1
if (rootData in inorderIndexMap):
return False
inorderIndex = inorderIndexMap[rootData]
if ((inStart < = inorderIndex and inorderIndex < = inEnd) = = False ):
return False
leftInorderStart = inStart
leftInorderEnd = inorderIndex - 1
rightInorderStart = inorderIndex + 1
rightInorderEnd = inEnd
if (checkInorderPreorderUtil(leftInorderStart,leftInorderEnd,preIndex,preorder,inorderIndexMap) = = False ):
return False
else :
return checkInorderPreorderUtil(rightInorderStart, rightInorderEnd,preIndex, preorder, inorderIndexMap)
def checkInorderPreorder(pre, inv,n):
inorderIndexMap = {}
for i in range (n):
inorderIndexMap[inv[i]] = i
preIndex = 0
if (checkInorderPreorderUtil( 0 , n - 1 , preIndex,pre, inorderIndexMap)):
return "No"
else :
return "Yes"
if __name__ = = '__main__' :
pre = [ 1 , 2 , 4 , 5 , 7 , 3 , 6 , 8 ]
inv = [ 4 , 2 , 5 , 7 , 1 , 6 , 8 , 3 ]
N = len (pre)
print (checkInorderPreorder(pre, inv, N))
|
C#
using System;
using System.Collections.Generic;
public class GFG
{
static int preIndex;
static Dictionary< int , int > inorderIndexMap = new Dictionary< int , int >();
static bool checkInorderPreorderUtil(
int inStart, int inEnd,
int []preorder)
{
if (inStart > inEnd)
return true ;
int rootData = preorder[preIndex];
preIndex++;
if (!inorderIndexMap.ContainsKey(rootData))
return false ;
int inorderIndex = inorderIndexMap[rootData];
if (!(inStart <= inorderIndex
&& inorderIndex <= inEnd))
return false ;
int leftInorderStart = inStart;
int leftInorderEnd = inorderIndex - 1;
int rightInorderStart = inorderIndex + 1;
int rightInorderEnd = inEnd;
if (!checkInorderPreorderUtil(
leftInorderStart, leftInorderEnd,preorder))
return false ;
else
return checkInorderPreorderUtil(
rightInorderStart, rightInorderEnd,
preorder);
}
static String checkInorderPreorder(
int []pre, int []inn, int n)
{
for ( int i = 0; i < n; i++)
inorderIndexMap.Add(inn[i], i);
preIndex = 0;
if (checkInorderPreorderUtil(
0, n - 1,
pre)) {
return "Yes" ;
}
else {
return "No" ;
}
}
public static void Main(String[] args)
{
int []pre = { 1, 2, 4, 5, 7, 3, 6, 8 };
int []inn = { 4, 2, 5, 7, 1, 6, 8, 3 };
int N = pre.Length;
Console.Write(checkInorderPreorder(pre, inn, N));
}
}
|
Javascript
<script>
let inorderIndexMap = new Map();
let preIndex;
function checkInorderPreorderUtil( inStart, inEnd, preorder)
{
if (inStart > inEnd)
return true ;
let rootData = preorder[preIndex];
preIndex++;
if (!inorderIndexMap.has(rootData))
return false ;
let inorderIndex = inorderIndexMap.get(rootData);
if (!(inStart <= inorderIndex
&& inorderIndex <= inEnd))
return false ;
let leftInorderStart = inStart;
let leftInorderEnd = inorderIndex - 1;
let rightInorderStart = inorderIndex + 1;
let rightInorderEnd = inEnd;
if (!checkInorderPreorderUtil(
leftInorderStart, leftInorderEnd, preorder))
return false ;
else
return checkInorderPreorderUtil(
rightInorderStart, rightInorderEnd, preorder);
}
function checkInorderPreorder(pre, inn, n)
{
for (let i = 0; i < n; i++)
inorderIndexMap.set(inn[i], i);
preIndex = 0;
if (checkInorderPreorderUtil(
0, n - 1,
pre )) {
return "Yes" ;
}
else {
return "No" ;
}
}
let pre = [ 1, 2, 4, 5, 7, 3, 6, 8 ];
let inn = [ 4, 2, 5, 7, 1, 6, 8, 3 ];
let N = pre.length;
document.write(checkInorderPreorder(pre, inn, N));
</script>
|
Time Complexity: O(N) Auxiliary Space: O(N)
Approach : solve this problem is to use a single array for the both preorder and inorder traversals. The key observation is that if the given traversals are valid for a binary tree, then the root of the tree must be the first element in the preorder traversal.
Here’s the implementation of this approach:
C++
#include <iostream>
#include <vector>
#include <unordered_map>
#include <stack>
#include <climits>
using namespace std;
bool GFG( const vector< int >& preorder, const vector< int >& inorder) {
if (preorder.size() != inorder.size()) {
return false ;
}
unordered_map< int , int > inorder_map;
for ( int i = 0; i < inorder.size(); ++i) {
inorder_map[inorder[i]] = i;
}
stack< int > st;
int root = INT_MIN;
for ( int val : preorder) {
if (inorder_map.find(val) == inorder_map.end()) {
return false ;
}
if (inorder_map[val] < inorder_map[root]) {
st.push(val);
} else {
while (!st.empty() && inorder_map[val] > inorder_map[st.top()]) {
root = st.top();
st.pop();
}
st.push(val);
}
}
return true ;
}
int main() {
vector< int > pre1 = {1, 2, 4, 5, 7, 3, 6, 8};
vector< int > in1 = {4, 2, 5, 7, 1, 6, 8, 3};
cout << (GFG(pre1, in1) ? "Yes" : "No" ) << endl;
vector< int > pre2 = {1, 2, 69, 5, 7, 3, 6, 8};
vector< int > in2 = {4, 2, 5, 7, 1, 6, 8, 3};
cout << (GFG(pre2, in2) ? "Yes" : "No" ) << endl;
return 0;
}
|
Java
import java.util.*;
public class Main {
public static boolean isBST(List<Integer> preorder,
List<Integer> inorder)
{
if (preorder.size() != inorder.size()) {
return false ;
}
Map<Integer, Integer> inorderMap = new HashMap<>();
for ( int i = 0 ; i < inorder.size(); ++i) {
inorderMap.put(inorder.get(i), i);
}
Stack<Integer> stack = new Stack<>();
int root
= preorder.get( 0 );
for ( int val : preorder) {
if (!inorderMap.containsKey(val)) {
return false ;
}
if (inorderMap.get(val)
< inorderMap.get(root)) {
stack.push(val);
}
else {
while (
!stack.isEmpty()
&& inorderMap.get(val)
> inorderMap.get(stack.peek())) {
root = stack.pop();
}
stack.push(val);
}
}
return true ;
}
public static void main(String[] args)
{
List<Integer> pre1
= Arrays.asList( 1 , 2 , 4 , 5 , 7 , 3 , 6 , 8 );
List<Integer> in1
= Arrays.asList( 4 , 2 , 5 , 7 , 1 , 6 , 8 , 3 );
System.out.println(isBST(pre1, in1) ? "Yes" : "No" );
List<Integer> pre2
= Arrays.asList( 1 , 2 , 69 , 5 , 7 , 3 , 6 , 8 );
List<Integer> in2
= Arrays.asList( 4 , 2 , 5 , 7 , 1 , 6 , 8 , 3 );
System.out.println(isBST(pre2, in2) ? "Yes" : "No" );
}
}
|
Python3
class TreeNode:
def __init__( self , val = 0 , left = None , right = None ):
self .val = val
self .left = left
self .right = right
def isBST(preorder, inorder):
if len (preorder) ! = len (inorder):
return False
inorder_map = {val: i for i, val in enumerate (inorder)}
stack = []
root = preorder[ 0 ]
for val in preorder:
if val not in inorder_map:
return False
if inorder_map[val] < inorder_map[root]:
stack.append(val)
else :
while stack and inorder_map[val] > inorder_map[stack[ - 1 ]]:
root = stack.pop()
stack.append(val)
return True
pre1 = [ 1 , 2 , 4 , 5 , 7 , 3 , 6 , 8 ]
in1 = [ 4 , 2 , 5 , 7 , 1 , 6 , 8 , 3 ]
print ( "Yes" if isBST(pre1, in1) else "No" )
pre2 = [ 1 , 2 , 69 , 5 , 7 , 3 , 6 , 8 ]
in2 = [ 4 , 2 , 5 , 7 , 1 , 6 , 8 , 3 ]
print ( "Yes" if isBST(pre2, in2) else "No" )
|
C#
using System;
using System.Collections.Generic;
class Program
{
static bool GFG(List< int > preorder, List< int > inorder)
{
if (preorder.Count != inorder.Count)
{
return false ;
}
Dictionary< int , int > inorderMap = new Dictionary< int , int >();
for ( int i = 0; i < inorder.Count; ++i)
{
inorderMap[inorder[i]] = i;
}
Stack< int > stack = new Stack< int >();
int root = preorder[0];
foreach ( int val in preorder)
{
if (!inorderMap.ContainsKey(val))
{
return false ;
}
if (inorderMap[val] < inorderMap[root])
{
stack.Push(val);
}
else
{
while (stack.Count > 0 && inorderMap[val] > inorderMap[stack.Peek()])
{
root = stack.Pop();
}
stack.Push(val);
}
}
return true ;
}
static void Main()
{
List< int > pre1 = new List< int > { 1, 2, 4, 5, 7, 3, 6, 8 };
List< int > in1 = new List< int > { 4, 2, 5, 7, 1, 6, 8, 3 };
Console.WriteLine(GFG(pre1, in1) ? "Yes" : "No" );
List< int > pre2 = new List< int > { 1, 2, 69, 5, 7, 3, 6, 8 };
List< int > in2 = new List< int > { 4, 2, 5, 7, 1, 6, 8, 3 };
Console.WriteLine(GFG(pre2, in2) ? "Yes" : "No" );
}
}
|
Javascript
function GFG(preorder, inorder) {
if (preorder.length !== inorder.length) {
return false ;
}
const inorderMap = new Map();
inorder.forEach((val, i) => {
inorderMap.set(val, i);
});
const stack = [];
let root = Number.MIN_SAFE_INTEGER;
for (const val of preorder) {
if (!inorderMap.has(val)) {
return false ;
}
if (inorderMap.get(val) < inorderMap.get(root)) {
stack.push(val);
} else {
while (stack.length > 0 &&
inorderMap.get(val) > inorderMap.get(stack[stack.length - 1])) {
root = stack.pop();
}
stack.push(val);
}
}
return true ;
}
const pre1 = [1, 2, 4, 5, 7, 3, 6, 8];
const in1 = [4, 2, 5, 7, 1, 6, 8, 3];
console.log(GFG(pre1, in1) ? "Yes" : "No" );
const pre2 = [1, 2, 69, 5, 7, 3, 6, 8];
const in2 = [4, 2, 5, 7, 1, 6, 8, 3];
console.log(GFG(pre2, in2) ? "Yes" : "No" );
|
|