Construct a tree from Inorder and Level order traversals

Last Updated : 23 Jul, 2026

Given two arrays in[] and level[] representing the inorder and level order traversals of a binary tree. Construct the binary tree and return its root.

Example: 

Input: in[] = [4, 8, 10, 12, 14, 20, 22], level[] = [20, 8, 22, 4, 12, 10, 14]
Output: [20, 8, 22, 4, 12, N, N, N, N, 10, 14]
Explanation: The constructed binary tree is:

112

Input: in[] = [4, 2, 5], level[] = [2, 4, 5]
Output: [2, 4, 5]
Explanation: The constructed binary tree is:

123
Try It Yourself
redirect icon

[Naive Approach] Using Recursion - O(n^3) Time and O(n^2) Space

The idea is that first element in the level order traversal is always the root of the current subtree. Using the root's position in the inorder traversal, we determine which nodes belong to the left and right subtrees, then partition the remaining level order elements accordingly and recursively construct both subtrees.

  • If the current inorder range is empty, return NULL.
  • Take the first element of the current level order traversal as the root.
  • Find the root's position in the inorder traversal to identify the left and right subtree ranges.
  • Partition the remaining level order elements into left and right subtrees based on whether they belong to the left or right inorder range.
  • Recursively construct the left subtree using inorder and level order traversal.
  • Recursively construct the right subtree, then return the root.
C++
#include <bits/stdc++.h>
using namespace std;

// Node of the binary tree.
class Node
{
  public:
    int data;
    Node *left, *right;

    Node(int val)
    {
        data = val;
        left = right = nullptr;
    }
};

// Returns the index of 'value' in inorder traversal
// between indices l and r.
int findIndex(vector<int> &in, int value, int l, int r)
{
    for (int i = l; i <= r; i++)
    {
        if (in[i] == value)
            return i;
    }
    return -1;
}

// Recursively constructs the binary tree.
Node *buildTreeUtil(vector<int> &in, vector<int> &level, int l, int r)
{

    // No nodes in this subtree.
    if (l > r)
        return nullptr;

    // The first node in level order is the root.
    Node *root = new Node(level[0]);

    // Find the root in inorder traversal.
    int rootIndex = findIndex(in, level[0], l, r);

    // Store level order traversals of left and right subtrees.
    vector<int> leftLevel;
    vector<int> rightLevel;

    // Partition the remaining level order elements.
    for (int i = 1; i < level.size(); i++)
    {

        int index = findIndex(in, level[i], l, r);

        if (index < rootIndex)
            leftLevel.push_back(level[i]);
        else if (index > rootIndex)
            rightLevel.push_back(level[i]);
    }

    // Construct left and right subtrees recursively.
    root->left = buildTreeUtil(in, leftLevel, l, rootIndex - 1);
    root->right = buildTreeUtil(in, rightLevel, rootIndex + 1, r);

    return root;
}

// Constructs the binary tree from inorder and level order traversals.
Node *buildTree(vector<int> &in, vector<int> &level)
{

    return buildTreeUtil(in, level, 0, in.size() - 1);
}

// Prints inorder traversal of the constructed tree.
void printLevelOrder(Node* root) {

    if (root == nullptr)
        return;

    vector<string> ans;
    queue<Node*> q;
    q.push(root);

    while (!q.empty()) {

        Node* curr = q.front();
        q.pop();

        if (curr == nullptr) {
            ans.push_back("N");
        }
        else {
            ans.push_back(to_string(curr->data));
            q.push(curr->left);
            q.push(curr->right);
        }
    }

    // Remove trailing nulls.
    while (!ans.empty() && ans.back() == "N")
        ans.pop_back();

    for (string &x : ans)
        cout << x << " ";

    cout << '\n';
}

int main()
{
    vector<int> in = {4, 8, 10, 12, 14, 20, 22};
    vector<int> level = {20, 8, 22, 4, 12, 10, 14};

    Node *root = buildTree(in, level);

    printLevelOrder(root);

    return 0;
}
Java
import java.util.*;

// Node of the binary tree.
class Node {
    int data;
    Node left, right;

    Node(int val)
    {
        data = val;
        left = right = null;
    }
}

class GFG {

    // Returns the index of 'value' in inorder traversal
    // between indices l and r.
    static int findIndex(int[] in, int value, int l, int r)
    {

        for (int i = l; i <= r; i++) {
            if (in[i] == value)
                return i;
        }

        return -1;
    }

    // Recursively constructs the binary tree.
    static Node buildTreeUtil(int[] in, int[] level, int l,
                              int r)
    {

        // No nodes in this subtree.
        if (l > r)
            return null;

        // The first node in level order is the root.
        Node root = new Node(level[0]);

        // Find the root in inorder traversal.
        int rootIndex = findIndex(in, level[0], l, r);

        // Store level order traversals of left and right
        // subtrees.
        int leftSize = rootIndex - l;
        int rightSize = r - rootIndex;

        int[] leftLevel = new int[leftSize];
        int[] rightLevel = new int[rightSize];

        int leftPtr = 0;
        int rightPtr = 0;

        // Partition the remaining level order elements.
        for (int i = 1; i < level.length; i++) {

            int index = findIndex(in, level[i], l, r);

            if (index < rootIndex)
                leftLevel[leftPtr++] = level[i];
            else if (index > rootIndex)
                rightLevel[rightPtr++] = level[i];
        }

        // Construct left and right subtrees recursively.
        root.left = buildTreeUtil(in, leftLevel, l,
                                  rootIndex - 1);
        root.right = buildTreeUtil(in, rightLevel,
                                   rootIndex + 1, r);

        return root;
    }

    // Constructs the binary tree from inorder and level
    // order traversals.
    static Node buildTree(int[] in, int[] level)
    {

        return buildTreeUtil(in, level, 0, in.length - 1);
    }

    // Prints the tree in level order using 'N' for null
    // nodes.
    static void printLevelOrder(Node root)
    {

        if (root == null)
            return;

        ArrayList<String> ans = new ArrayList<>();
        Queue<Node> q = new LinkedList<>();

        q.offer(root);

        while (!q.isEmpty()) {

            Node curr = q.poll();

            if (curr == null) {
                ans.add("N");
            }
            else {

                ans.add(String.valueOf(curr.data));

                q.offer(curr.left);
                q.offer(curr.right);
            }
        }

        // Remove trailing nulls.
        while (!ans.isEmpty()
               && ans.get(ans.size() - 1).equals("N"))
            ans.remove(ans.size() - 1);

        for (String s : ans)
            System.out.print(s + " ");

        System.out.println();
    }

    public static void main(String[] args)
    {

        int[] in = { 4, 8, 10, 12, 14, 20, 22 };
        int[] level = { 20, 8, 22, 4, 12, 10, 14 };

        Node root = buildTree(in, level);

        printLevelOrder(root);
    }
}
Python
from collections import deque

# Node of the binary tree.
class Node:
    def __init__(self, val):
        self.data = val
        self.left = None
        self.right = None


# Returns the index of 'value' in inorder traversal
# between indices l and r.
def findIndex(inorder, value, l, r):

    for i in range(l, r + 1):
        if inorder[i] == value:
            return i

    return -1


# Recursively constructs the binary tree.
def buildTreeUtil(inorder, level, l, r):

    # No nodes in this subtree.
    if l > r:
        return None

    # The first node in level order is the root.
    root = Node(level[0])

    # Find the root in inorder traversal.
    rootIndex = findIndex(inorder, level[0], l, r)

    # Store level order traversals of left and right subtrees.
    leftLevel = []
    rightLevel = []

    # Partition the remaining level order elements.
    for i in range(1, len(level)):

        index = findIndex(inorder, level[i], l, r)

        if index < rootIndex:
            leftLevel.append(level[i])
        elif index > rootIndex:
            rightLevel.append(level[i])

    # Construct left and right subtrees recursively.
    root.left = buildTreeUtil(inorder, leftLevel, l, rootIndex - 1)
    root.right = buildTreeUtil(inorder, rightLevel, rootIndex + 1, r)

    return root


# Constructs the binary tree from inorder and level order traversals.
def buildTree(inorder, level):

    return buildTreeUtil(inorder, level, 0, len(inorder) - 1)


# Prints the tree in level order using 'N' for null nodes.
def printLevelOrder(root):

    if root is None:
        return

    ans = []
    q = deque([root])

    while q:

        curr = q.popleft()

        if curr is None:
            ans.append("N")
        else:
            ans.append(str(curr.data))
            q.append(curr.left)
            q.append(curr.right)

    # Remove trailing nulls.
    while ans and ans[-1] == "N":
        ans.pop()

    print(*ans)


# Driver code
if __name__ == "__main__":
    inorder = [4, 8, 10, 12, 14, 20, 22]
    level = [20, 8, 22, 4, 12, 10, 14]

    root = buildTree(inorder, level)

    printLevelOrder(root)
C#
using System;
using System.Collections.Generic;

// Node of the binary tree.
class Node {
    public int data;
    public Node left, right;

    public Node(int val)
    {
        data = val;
        left = right = null;
    }
}

class GFG {
    // Returns the index of 'value' in inorder traversal
    // between indices l and r.
    static int FindIndex(int[] inorder, int value, int l,
                         int r)
    {
        for (int i = l; i <= r; i++) {
            if (inorder[i] == value)
                return i;
        }

        return -1;
    }

    // Recursively constructs the binary tree.
    static Node BuildTreeUtil(int[] inorder, int[] level,
                              int l, int r)
    {
        // No nodes in this subtree.
        if (l > r)
            return null;

        // The first node in level order is the root.
        Node root = new Node(level[0]);

        // Find the root in inorder traversal.
        int rootIndex = FindIndex(inorder, level[0], l, r);

        // Store level order traversals of left and right
        // subtrees.
        int leftSize = rootIndex - l;
        int rightSize = r - rootIndex;

        int[] leftLevel = new int[leftSize];
        int[] rightLevel = new int[rightSize];

        int leftPtr = 0;
        int rightPtr = 0;

        // Partition the remaining level order elements.
        for (int i = 1; i < level.Length; i++) {
            int index = FindIndex(inorder, level[i], l, r);

            if (index < rootIndex)
                leftLevel[leftPtr++] = level[i];
            else if (index > rootIndex)
                rightLevel[rightPtr++] = level[i];
        }

        // Construct left and right subtrees recursively.
        root.left = BuildTreeUtil(inorder, leftLevel, l,
                                  rootIndex - 1);
        root.right = BuildTreeUtil(inorder, rightLevel,
                                   rootIndex + 1, r);

        return root;
    }

    // Constructs the binary tree from inorder and level
    // order traversals.
    static Node buildTree(int[] inorder, int[] level)
    {
        return BuildTreeUtil(inorder, level, 0,
                             inorder.Length - 1);
    }

    // Prints the tree in level order using 'N' for null
    // nodes.
    static void PrintLevelOrder(Node root)
    {
        if (root == null)
            return;

        List<string> ans = new List<string>();
        Queue<Node> q = new Queue<Node>();

        q.Enqueue(root);

        while (q.Count > 0) {
            Node curr = q.Dequeue();

            if (curr == null) {
                ans.Add("N");
            }
            else {
                ans.Add(curr.data.ToString());

                q.Enqueue(curr.left);
                q.Enqueue(curr.right);
            }
        }

        // Remove trailing nulls.
        while (ans.Count > 0 && ans[ans.Count - 1] == "N")
            ans.RemoveAt(ans.Count - 1);

        foreach(string x in ans) Console.Write(x + " ");

        Console.WriteLine();
    }

    static void Main()
    {
        int[] inorder = { 4, 8, 10, 12, 14, 20, 22 };
        int[] level = { 20, 8, 22, 4, 12, 10, 14 };

        Node root = buildTree(inorder, level);

        PrintLevelOrder(root);
    }
}
JavaScript
// Node of the binary tree.
class Node {
    constructor(val)
    {
        this.data = val;
        this.left = null;
        this.right = null;
    }
}

// Returns the index of 'value' in inorder traversal
// between indices l and r.
function findIndex(inorder, value, l, r)
{
    for (let i = l; i <= r; i++) {
        if (inorder[i] === value)
            return i;
    }

    return -1;
}

// Recursively constructs the binary tree.
function buildTreeUtil(inorder, level, l, r)
{
    // No nodes in this subtree.
    if (l > r)
        return null;

    // The first node in level order is the root.
    let root = new Node(level[0]);

    // Find the root in inorder traversal.
    let rootIndex = findIndex(inorder, level[0], l, r);

    // Store level order traversals of left and right
    // subtrees.
    let leftLevel = [];
    let rightLevel = [];

    // Partition the remaining level order elements.
    for (let i = 1; i < level.length; i++) {

        let index = findIndex(inorder, level[i], l, r);

        if (index < rootIndex)
            leftLevel.push(level[i]);
        else if (index > rootIndex)
            rightLevel.push(level[i]);
    }

    // Construct left and right subtrees recursively.
    root.left = buildTreeUtil(inorder, leftLevel, l,
                              rootIndex - 1);
    root.right = buildTreeUtil(inorder, rightLevel,
                               rootIndex + 1, r);

    return root;
}

// Constructs the binary tree from inorder and level order
// traversals.
function buildTree(inorder, level)
{
    return buildTreeUtil(inorder, level, 0,
                         inorder.length - 1);
}

// Prints the tree in level order using 'N' for null nodes.
function printLevelOrder(root)
{
    if (root === null)
        return;

    let ans = [];
    let q = [];

    q.push(root);

    while (q.length > 0) {

        let curr = q.shift();

        if (curr === null) {
            ans.push("N");
        }
        else {
            ans.push(curr.data.toString());

            q.push(curr.left);
            q.push(curr.right);
        }
    }

    // Remove trailing nulls.
    while (ans.length > 0 && ans[ans.length - 1] === "N")
        ans.pop();

    console.log(ans.join(" "));
}

// Driver code
let inorder = [ 4, 8, 10, 12, 14, 20, 22 ];
let level = [ 20, 8, 22, 4, 12, 10, 14 ];

let root = buildTree(inorder, level);

printLevelOrder(root);

Output
20 8 22 4 12 N N N N 10 14 

[Better Approach] Using Recursion With Hash map - O(n^2) Time and O(n^2) Space

The idea is the same as the previous approach, but we use a hash to speed up the construction. A hash map stores the index of each node in the inorder traversal, allowing the root's position to be found in O(1) time. Alternatively, a hash set can be used to quickly determine whether a node belongs to the left subtree after locating the root in the inorder traversal.

  • Store the index of each node in the inorder traversal using a hash map for O(1) lookup.
  • Take the first element of the current level order traversal as the root.
  • Use the hash map to find the root's position in the inorder traversal, which divides the left and right subtree ranges.
  • Partition the remaining level order elements into left and right subtrees based on their inorder indices.
  • Recursively construct the left subtree using inorder and level order traversal.
  • Recursively construct the right subtree, then return the root.
C++
#include <bits/stdc++.h>
using namespace std;

// Node of the binary tree.
class Node
{
  public:
    int data;
    Node *left, *right;

    Node(int val)
    {
        data = val;
        left = right = nullptr;
    }
};

// Recursively constructs the binary tree.
Node *buildTreeUtil(const unordered_map<int, int> &inMap, vector<int> &level, int l, int r)
{
    // No nodes in this subtree.
    if (l > r)
        return nullptr;

    // The first element of level order is the root.
    Node *root = new Node(level[0]);

    // Find the root's position in inorder traversal.
    int rootIndex = inMap.at(level[0]);

    // Store level order traversals of left and right subtrees.
    vector<int> leftLevel;
    vector<int> rightLevel;

    // Partition the remaining level order elements.
    for (int i = 1; i < level.size(); i++)
    {

        if (inMap.at(level[i]) < rootIndex)
            leftLevel.push_back(level[i]);
        else
            rightLevel.push_back(level[i]);
    }

    // Construct left and right subtrees recursively.
    root->left = buildTreeUtil(inMap, leftLevel, l, rootIndex - 1);
    root->right = buildTreeUtil(inMap, rightLevel, rootIndex + 1, r);

    return root;
}

// Constructs the binary tree from inorder and level order traversals.
Node *buildTree(vector<int> &in, vector<int> &level)
{
    // Store the index of every node in inorder traversal.
    unordered_map<int, int> inMap;

    for (int i = 0; i < in.size(); i++)
        inMap[in[i]] = i;

    return buildTreeUtil(inMap, level, 0, in.size() - 1);
}

// Prints the tree in level order using 'N' for null nodes.
void printLevelOrder(Node *root)
{
    if (root == nullptr)
        return;

    vector<string> ans;
    queue<Node *> q;
    q.push(root);

    while (!q.empty())
    {

        Node *curr = q.front();
        q.pop();

        if (curr == nullptr)
        {
            ans.push_back("N");
        }
        else
        {
            ans.push_back(to_string(curr->data));
            q.push(curr->left);
            q.push(curr->right);
        }
    }

    // Remove trailing null nodes.
    while (!ans.empty() && ans.back() == "N")
        ans.pop_back();

    for (string &x : ans)
        cout << x << " ";

    cout << '\n';
}

int main()
{

    vector<int> in = {4, 8, 10, 12, 14, 20, 22};
    vector<int> level = {20, 8, 22, 4, 12, 10, 14};

    Node *root = buildTree(in, level);

    printLevelOrder(root);

    return 0;
}
Java
import java.util.*;

// Node of the binary tree.
class Node {
    int data;
    Node left, right;

    Node(int val)
    {
        data = val;
        left = right = null;
    }
}

public class GFG {

    // Recursively constructs the binary tree.
    static Node
    buildTreeUtil(HashMap<Integer, Integer> inMap,
                  int[] level, int l, int r)
    {
        // No nodes in this subtree.
        if (l > r)
            return null;

        // The first element of level order is the root.
        Node root = new Node(level[0]);

        // Find the root's position in inorder traversal.
        int rootIndex = inMap.get(level[0]);

        // Store level order traversals of left and right
        // subtrees.
        ArrayList<Integer> leftList = new ArrayList<>();
        ArrayList<Integer> rightList = new ArrayList<>();

        // Partition the remaining level order elements.
        for (int i = 1; i < level.length; i++) {

            if (inMap.get(level[i]) < rootIndex)
                leftList.add(level[i]);
            else
                rightList.add(level[i]);
        }

        // Convert ArrayLists into arrays.
        int[] leftLevel = new int[leftList.size()];
        int[] rightLevel = new int[rightList.size()];

        for (int i = 0; i < leftList.size(); i++)
            leftLevel[i] = leftList.get(i);

        for (int i = 0; i < rightList.size(); i++)
            rightLevel[i] = rightList.get(i);

        // Construct left and right subtrees recursively.
        root.left = buildTreeUtil(inMap, leftLevel, l,
                                  rootIndex - 1);
        root.right = buildTreeUtil(inMap, rightLevel,
                                   rootIndex + 1, r);

        return root;
    }

    // Constructs the binary tree from inorder and level
    // order traversals.
    static Node buildTree(int[] in, int[] level)
    {
        // Store the index of every node in inorder
        // traversal.
        HashMap<Integer, Integer> inMap = new HashMap<>();

        for (int i = 0; i < in.length; i++)
            inMap.put(in[i], i);

        return buildTreeUtil(inMap, level, 0,
                             in.length - 1);
    }

    // Prints the tree in level order using 'N' for null
    // nodes.
    static void printLevelOrder(Node root)
    {
        if (root == null)
            return;

        ArrayList<String> ans = new ArrayList<>();
        Queue<Node> q = new LinkedList<>();

        q.offer(root);

        while (!q.isEmpty()) {

            Node curr = q.poll();

            if (curr == null) {
                ans.add("N");
            }
            else {
                ans.add(String.valueOf(curr.data));
                q.offer(curr.left);
                q.offer(curr.right);
            }
        }

        // Remove trailing null nodes.
        while (!ans.isEmpty()
               && ans.get(ans.size() - 1).equals("N"))
            ans.remove(ans.size() - 1);

        for (String x : ans)
            System.out.print(x + " ");

        System.out.println();
    }

    public static void main(String[] args)
    {

        int[] in = { 4, 8, 10, 12, 14, 20, 22 };
        int[] level = { 20, 8, 22, 4, 12, 10, 14 };

        Node root = buildTree(in, level);

        printLevelOrder(root);
    }
}
Python
from collections import deque

# Node of the binary tree.
class Node:
    def __init__(self, val):
        self.data = val
        self.left = None
        self.right = None


# Recursively constructs the binary tree.
def buildTreeUtil(inMap, level, l, r):

    # No nodes in this subtree.
    if l > r:
        return None

    # The first element of level order is the root.
    root = Node(level[0])

    # Find the root's position in inorder traversal.
    rootIndex = inMap[level[0]]

    # Store level order traversals of left and right subtrees.
    leftLevel = []
    rightLevel = []

    # Partition the remaining level order elements.
    for i in range(1, len(level)):

        if inMap[level[i]] < rootIndex:
            leftLevel.append(level[i])
        else:
            rightLevel.append(level[i])

    # Construct left and right subtrees recursively.
    root.left = buildTreeUtil(inMap, leftLevel, l, rootIndex - 1)
    root.right = buildTreeUtil(inMap, rightLevel, rootIndex + 1, r)

    return root


# Constructs the binary tree from inorder and level order traversals.
def buildTree(inorder, level):

    # Store the index of every node in inorder traversal.
    inMap = {}

    for i in range(len(inorder)):
        inMap[inorder[i]] = i

    return buildTreeUtil(inMap, level, 0, len(inorder) - 1)


# Prints the tree in level order using 'N' for null nodes.
def printLevelOrder(root):

    if root is None:
        return

    ans = []
    q = deque([root])

    while q:

        curr = q.popleft()

        if curr is None:
            ans.append("N")
        else:
            ans.append(str(curr.data))
            q.append(curr.left)
            q.append(curr.right)

    # Remove trailing null nodes.
    while ans and ans[-1] == "N":
        ans.pop()

    print(*ans)


# Driver code
if __name__ == "__main__":
    inorder = [4, 8, 10, 12, 14, 20, 22]
    level = [20, 8, 22, 4, 12, 10, 14]

    root = buildTree(inorder, level)

    printLevelOrder(root)
C#
using System;
using System.Collections.Generic;

// Node of the binary tree.
class Node {
    public int data;
    public Node left, right;

    public Node(int val)
    {
        data = val;
        left = right = null;
    }
}

class GFG {
    // Recursively constructs the binary tree.
    static Node BuildTreeUtil(Dictionary<int, int> inMap,
                              int[] level, int l, int r)
    {
        // No nodes in this subtree.
        if (l > r)
            return null;

        // The first element of level order is the root.
        Node root = new Node(level[0]);

        // Find the root's position in inorder traversal.
        int rootIndex = inMap[level[0]];

        // Store level order traversals of left and right
        // subtrees.
        List<int> leftList = new List<int>();
        List<int> rightList = new List<int>();

        // Partition the remaining level order elements.
        for (int i = 1; i < level.Length; i++) {
            if (inMap[level[i]] < rootIndex)
                leftList.Add(level[i]);
            else
                rightList.Add(level[i]);
        }

        // Convert lists into arrays.
        int[] leftLevel = leftList.ToArray();
        int[] rightLevel = rightList.ToArray();

        // Construct left and right subtrees recursively.
        root.left = BuildTreeUtil(inMap, leftLevel, l,
                                  rootIndex - 1);
        root.right = BuildTreeUtil(inMap, rightLevel,
                                   rootIndex + 1, r);

        return root;
    }

    // Constructs the binary tree from inorder and level
    // order traversals.
    static Node buildTree(int[] inorder, int[] level)
    {
        // Store the index of every node in inorder
        // traversal.
        Dictionary<int, int> inMap
            = new Dictionary<int, int>();

        for (int i = 0; i < inorder.Length; i++)
            inMap[inorder[i]] = i;

        return BuildTreeUtil(inMap, level, 0,
                             inorder.Length - 1);
    }

    // Prints the tree in level order using 'N' for null
    // nodes.
    static void PrintLevelOrder(Node root)
    {
        if (root == null)
            return;

        List<string> ans = new List<string>();
        Queue<Node> q = new Queue<Node>();

        q.Enqueue(root);

        while (q.Count > 0) {
            Node curr = q.Dequeue();

            if (curr == null) {
                ans.Add("N");
            }
            else {
                ans.Add(curr.data.ToString());
                q.Enqueue(curr.left);
                q.Enqueue(curr.right);
            }
        }

        // Remove trailing null nodes.
        while (ans.Count > 0 && ans[ans.Count - 1] == "N")
            ans.RemoveAt(ans.Count - 1);

        foreach(string x in ans) Console.Write(x + " ");

        Console.WriteLine();
    }

    static void Main()
    {
        int[] inorder = { 4, 8, 10, 12, 14, 20, 22 };
        int[] level = { 20, 8, 22, 4, 12, 10, 14 };

        Node root = buildTree(inorder, level);

        PrintLevelOrder(root);
    }
}
JavaScript
// Node of the binary tree.
class Node {
    constructor(val)
    {
        this.data = val;
        this.left = null;
        this.right = null;
    }
}

// Recursively constructs the binary tree.
function buildTreeUtil(inMap, level, l, r)
{
    // No nodes in this subtree.
    if (l > r)
        return null;

    // The first element of level order is the root.
    let root = new Node(level[0]);

    // Find the root's position in inorder traversal.
    let rootIndex = inMap.get(level[0]);

    // Store level order traversals of left and right
    // subtrees.
    let leftLevel = [];
    let rightLevel = [];

    // Partition the remaining level order elements.
    for (let i = 1; i < level.length; i++) {

        if (inMap.get(level[i]) < rootIndex)
            leftLevel.push(level[i]);
        else
            rightLevel.push(level[i]);
    }

    // Construct left and right subtrees recursively.
    root.left
        = buildTreeUtil(inMap, leftLevel, l, rootIndex - 1);
    root.right = buildTreeUtil(inMap, rightLevel,
                               rootIndex + 1, r);

    return root;
}

// Constructs the binary tree from inorder and level order
// traversals.
function buildTree(inorder, level)
{
    // Store the index of every node in inorder traversal.
    let inMap = new Map();

    for (let i = 0; i < inorder.length; i++)
        inMap.set(inorder[i], i);

    return buildTreeUtil(inMap, level, 0,
                         inorder.length - 1);
}

// Prints the tree in level order using 'N' for null nodes.
function printLevelOrder(root)
{
    if (root === null)
        return;

    let ans = [];
    let q = [];

    q.push(root);

    while (q.length > 0) {

        let curr = q.shift();

        if (curr === null) {
            ans.push("N");
        }
        else {
            ans.push(curr.data.toString());
            q.push(curr.left);
            q.push(curr.right);
        }
    }

    // Remove trailing null nodes.
    while (ans.length > 0 && ans[ans.length - 1] === "N")
        ans.pop();

    console.log(ans.join(" "));
}

// Driver code
let inorder = [ 4, 8, 10, 12, 14, 20, 22 ];
let level = [ 20, 8, 22, 4, 12, 10, 14 ];

let root = buildTree(inorder, level);

printLevelOrder(root);

Output
20 8 22 4 12 N N N N 10 14 

[Expected Approach] Using Queue and Hash map - O(n) Time and O(n) Space

The idea is to process the nodes in the same order as they appear in the level order traversal. The first element of the level order array becomes the root. For every node, we maintain its valid inorder range. Using the root's index in the inorder array, we determine whether its left and right subtrees exist. If they do, the next unused elements in the level order traversal become the roots of those subtrees, and they are processed similarly using a queue.

  • Store the index of every node in the inorder traversal using a hash map for O(1) index lookup.
  • Create the root from the first element of the level order traversal and push it into a queue along with its inorder range.
  • Process each node from the queue and find its position in the inorder traversal using the hash map.
  • If a left subtree exists, create its root using the next unused level order element and push it into the queue with its inorder range.
  • If a right subtree exists, create its root using the next unused level order element and push it into the queue with its inorder range.
  • Continue until the queue becomes empty, then return the constructed root.
C++
#include <bits/stdc++.h>
using namespace std;

// Node of the binary tree.
class Node
{
  public:
    int data;
    Node *left, *right;

    Node(int val)
    {
        data = val;
        left = right = nullptr;
    }
};

// Constructs the binary tree from inorder and level order traversals.
Node *buildTree(vector<int> &in, vector<int> &level)
{
    int n = in.size();

    // Empty tree.
    if (n == 0)
        return nullptr;

    // Store the index of every node in inorder traversal.
    unordered_map<int, int> inMap;
    for (int i = 0; i < n; i++)
        inMap[in[i]] = i;

    // Create the root node.
    Node *root = new Node(level[0]);

    // Points to the next unused element in level order traversal.
    int index = 1;

    // Queue stores:
    // {current node, left inorder index, right inorder index}
    queue<tuple<Node *, int, int>> q;
    q.push({root, 0, n - 1});

    // Construct the tree in level order.
    while (!q.empty())
    {
        auto [node, left, right] = q.front();
        q.pop();

        // Position of the current node in inorder traversal.
        int rootIndex = inMap[node->data];

        // If the left subtree exists, the next unused level order
        // element becomes its root.
        if (left < rootIndex && index < n)
        {
            node->left = new Node(level[index++]);
            q.push({node->left, left, rootIndex - 1});
        }

        // If the right subtree exists, the next unused level order
        // element becomes its root.
        if (rootIndex < right && index < n)
        {
            node->right = new Node(level[index++]);
            q.push({node->right, rootIndex + 1, right});
        }
    }

    return root;
}

// Prints the tree in level order using 'N' for null nodes.
void printLevelOrder(Node *root)
{
    if (root == nullptr)
        return;

    vector<string> ans;
    queue<Node *> q;
    q.push(root);

    while (!q.empty())
    {
        Node *curr = q.front();
        q.pop();

        if (curr == nullptr)
        {
            ans.push_back("N");
        }
        else
        {
            ans.push_back(to_string(curr->data));
            q.push(curr->left);
            q.push(curr->right);
        }
    }

    // Remove trailing null nodes.
    while (!ans.empty() && ans.back() == "N")
        ans.pop_back();

    for (string &x : ans)
        cout << x << " ";

    cout << '\n';
}

int main()
{
    vector<int> in = {4, 8, 10, 12, 14, 20, 22};
    vector<int> level = {20, 8, 22, 4, 12, 10, 14};

    Node *root = buildTree(in, level);

    printLevelOrder(root);

    return 0;
}
Java
import java.util.*;

// Node of the binary tree.
class Node {
    int data;
    Node left, right;

    Node(int val)
    {
        data = val;
        left = right = null;
    }
}

public class GFG {

    // Constructs the binary tree from inorder and level
    // order traversals.
    static Node buildTree(int[] in, int[] level)
    {
        int n = in.length;

        // Empty tree.
        if (n == 0)
            return null;

        // Store the index of every node in inorder
        // traversal.
        HashMap<Integer, Integer> inMap = new HashMap<>();

        for (int i = 0; i < n; i++)
            inMap.put(in[i], i);

        // Create the root node.
        Node root = new Node(level[0]);

        // Points to the next unused element in level order
        // traversal.
        int index = 1;

        // Queue stores:
        // {current node, left inorder index, right inorder
        // index}
        Queue<Object[]> q = new LinkedList<>();
        q.offer(new Object[] { root, 0, n - 1 });

        // Construct the tree in level order.
        while (!q.isEmpty()) {

            Object[] curr = q.poll();

            Node node = (Node)curr[0];
            int left = (Integer)curr[1];
            int right = (Integer)curr[2];

            // Position of the current node in inorder
            // traversal.
            int rootIndex = inMap.get(node.data);

            // If the left subtree exists, the next unused
            // level order element becomes its root.
            if (left < rootIndex && index < n) {

                node.left = new Node(level[index++]);

                q.offer(new Object[] { node.left, left,
                                       rootIndex - 1 });
            }

            // If the right subtree exists, the next unused
            // level order element becomes its root.
            if (rootIndex < right && index < n) {

                node.right = new Node(level[index++]);

                q.offer(new Object[] {
                    node.right, rootIndex + 1, right });
            }
        }

        return root;
    }

    // Prints the tree in level order using 'N' for null
    // nodes.
    static void printLevelOrder(Node root)
    {

        if (root == null)
            return;

        ArrayList<String> ans = new ArrayList<>();
        Queue<Node> q = new LinkedList<>();
        q.offer(root);

        while (!q.isEmpty()) {

            Node curr = q.poll();

            if (curr == null) {
                ans.add("N");
            }
            else {
                ans.add(String.valueOf(curr.data));
                q.offer(curr.left);
                q.offer(curr.right);
            }
        }

        // Remove trailing null nodes.
        while (!ans.isEmpty()
               && ans.get(ans.size() - 1).equals("N"))
            ans.remove(ans.size() - 1);

        for (String x : ans)
            System.out.print(x + " ");

        System.out.println();
    }

    public static void main(String[] args)
    {

        int[] in = { 4, 8, 10, 12, 14, 20, 22 };
        int[] level = { 20, 8, 22, 4, 12, 10, 14 };

        Node root = buildTree(in, level);

        printLevelOrder(root);
    }
}
Python
from collections import deque

# Node of the binary tree.
class Node:
    def __init__(self, val):
        self.data = val
        self.left = None
        self.right = None


# Constructs the binary tree from inorder and level
# order traversals.
def buildTree(inorder, level):

    n = len(inorder)

    # Empty tree.
    if n == 0:
        return None

    # Store the index of every node in inorder traversal.
    inMap = {}

    for i in range(n):
        inMap[inorder[i]] = i

    # Create the root node.
    root = Node(level[0])

    # Points to the next unused element in level order traversal.
    index = 1

    # Queue stores:
    # (current node, left inorder index, right inorder index)
    q = deque()
    q.append((root, 0, n - 1))

    # Construct the tree in level order.
    while q:

        node, left, right = q.popleft()

        # Position of the current node in inorder traversal.
        rootIndex = inMap[node.data]

        # If the left subtree exists, the next unused level order
        # element becomes its root.
        if left < rootIndex and index < n:

            node.left = Node(level[index])
            index += 1

            q.append((node.left, left, rootIndex - 1))

        # If the right subtree exists, the next unused level order
        # element becomes its root.
        if rootIndex < right and index < n:

            node.right = Node(level[index])
            index += 1

            q.append((node.right, rootIndex + 1, right))

    return root


# Prints the tree in level order using 'N' for null nodes.
def printLevelOrder(root):

    if root is None:
        return

    ans = []
    q = deque([root])

    while q:

        curr = q.popleft()

        if curr is None:
            ans.append("N")
        else:
            ans.append(str(curr.data))
            q.append(curr.left)
            q.append(curr.right)

    # Remove trailing null nodes.
    while ans and ans[-1] == "N":
        ans.pop()

    print(*ans)


# Driver code
if __name__ == "__main__":
    inorder = [4, 8, 10, 12, 14, 20, 22]
    level = [20, 8, 22, 4, 12, 10, 14]

    root = buildTree(inorder, level)

    printLevelOrder(root)
C#
using System;
using System.Collections.Generic;

// Node of the binary tree.
class Node {
    public int data;
    public Node left, right;

    public Node(int val)
    {
        data = val;
        left = right = null;
    }
}

class GFG {
    // Constructs the binary tree from inorder and level
    // order traversals.
    static Node buildTree(int[] inorder, int[] level)
    {
        int n = inorder.Length;

        // Empty tree.
        if (n == 0)
            return null;

        // Store the index of every node in inorder
        // traversal.
        Dictionary<int, int> inMap
            = new Dictionary<int, int>();

        for (int i = 0; i < n; i++)
            inMap[inorder[i]] = i;

        // Create the root node.
        Node root = new Node(level[0]);

        // Points to the next unused element in level order
        // traversal.
        int index = 1;

        // Queue stores:
        // (current node, left inorder index, right inorder
        // index)
        Queue<(Node node, int left, int right)> q
            = new Queue<(Node node, int left, int right)>();

        q.Enqueue((root, 0, n - 1));

        // Construct the tree in level order.
        while (q.Count > 0) {
            var curr = q.Dequeue();

            Node node = curr.node;
            int left = curr.left;
            int right = curr.right;

            // Position of the current node in inorder
            // traversal.
            int rootIndex = inMap[node.data];

            // If the left subtree exists, the next unused
            // level order element becomes its root.
            if (left < rootIndex && index < n) {
                node.left = new Node(level[index++]);

                q.Enqueue((node.left, left, rootIndex - 1));
            }

            // If the right subtree exists, the next unused
            // level order element becomes its root.
            if (rootIndex < right && index < n) {
                node.right = new Node(level[index++]);

                q.Enqueue(
                    (node.right, rootIndex + 1, right));
            }
        }

        return root;
    }

    // Prints the tree in level order using 'N' for null
    // nodes.
    static void PrintLevelOrder(Node root)
    {
        if (root == null)
            return;

        List<string> ans = new List<string>();
        Queue<Node> q = new Queue<Node>();
        q.Enqueue(root);

        while (q.Count > 0) {
            Node curr = q.Dequeue();

            if (curr == null) {
                ans.Add("N");
            }
            else {
                ans.Add(curr.data.ToString());
                q.Enqueue(curr.left);
                q.Enqueue(curr.right);
            }
        }

        // Remove trailing null nodes.
        while (ans.Count > 0 && ans[ans.Count - 1] == "N")
            ans.RemoveAt(ans.Count - 1);

        foreach(string x in ans) Console.Write(x + " ");

        Console.WriteLine();
    }

    static void Main()
    {
        int[] inorder = { 4, 8, 10, 12, 14, 20, 22 };
        int[] level = { 20, 8, 22, 4, 12, 10, 14 };

        Node root = buildTree(inorder, level);

        PrintLevelOrder(root);
    }
}
JavaScript
// Node of the binary tree.
class Node {
    constructor(val)
    {
        this.data = val;
        this.left = null;
        this.right = null;
    }
}

// Constructs the binary tree from inorder and level
// order traversals.
function buildTree(inorder, level)
{
    const n = inorder.length;

    // Empty tree.
    if (n === 0)
        return null;

    // Store the index of every node in inorder traversal.
    const inMap = new Map();

    for (let i = 0; i < n; i++)
        inMap.set(inorder[i], i);

    // Create the root node.
    const root = new Node(level[0]);

    // Points to the next unused element in level order
    // traversal.
    let index = 1;

    // Queue stores:
    // [current node, left inorder index, right inorder
    // index]
    const q = [];
    q.push([ root, 0, n - 1 ]);

    // Construct the tree in level order.
    while (q.length > 0) {

        const [node, left, right] = q.shift();

        // Position of the current node in inorder
        // traversal.
        const rootIndex = inMap.get(node.data);

        // If the left subtree exists, the next unused level
        // order element becomes its root.
        if (left < rootIndex && index < n) {

            node.left = new Node(level[index++]);

            q.push([ node.left, left, rootIndex - 1 ]);
        }

        // If the right subtree exists, the next unused
        // level order element becomes its root.
        if (rootIndex < right && index < n) {

            node.right = new Node(level[index++]);

            q.push([ node.right, rootIndex + 1, right ]);
        }
    }

    return root;
}

// Prints the tree in level order using 'N' for null nodes.
function printLevelOrder(root)
{
    if (root === null)
        return;

    const ans = [];
    const q = [];
    q.push(root);

    while (q.length > 0) {

        const curr = q.shift();

        if (curr === null) {
            ans.push("N");
        }
        else {
            ans.push(curr.data.toString());
            q.push(curr.left);
            q.push(curr.right);
        }
    }

    // Remove trailing null nodes.
    while (ans.length > 0 && ans[ans.length - 1] === "N")
        ans.pop();

    console.log(ans.join(" "));
}

// Driver code
const inorder = [ 4, 8, 10, 12, 14, 20, 22 ];
const level = [ 20, 8, 22, 4, 12, 10, 14 ];

const root = buildTree(inorder, level);

printLevelOrder(root);

Output
20 8 22 4 12 N N N N 10 14 
Comment