Full Binary Tree using its Preorder and Mirror's Preorder

Last Updated : 27 May, 2026

Given two arrays pre[] and preMirror[] of size n containing unique elements, where pre[] represents the preorder traversal of a full binary tree and preMirror[] represents the preorder traversal of its mirror tree, construct the original full binary tree using these traversals.

Note: A general binary tree cannot be uniquely constructed using these two traversals. However, a full binary tree can be constructed uniquely from the given traversals without any ambiguity.

Examples: 

Input: pre[] = {0,1,2}, preMirror[] = {0,2,1}
Output: {0, 1, 2}
Explanation: The tree will look like

2056958016

Input: pre[] = {1, 2, 4, 5, 3, 6, 7}, preMirror[] = {1, 3, 7, 6, 2, 5, 4}
Output: {1, 2, 4, 5, 3, 6, 7}
Explanation: The tree will look like

construct-full-binary-tree-using-its-preorder-traversal-and-preorder-traversal-of-its-mirror-tree
Try It Yourself
redirect icon

[Naive Approach] Linear Search in Mirror Preorder – O(n²) Time and O(n) Space

We use pre[] to pick nodes in root order, and preMirror[] to determine how the tree is split into left and right subtrees.

  • Take the first element of pre[] as the root.
  • Maintain a variable preIndex to track the current position in pre[].
  • For the next element in pre[], find its position in preMirror[]. This position divides the current range into left subtree range and right subtree range. In the above example pre[] = {1, 2, 4, 5, 3, 6, 7}, preMirror[] = {1, 3, 7, 6, 2, 5, 4}. Using the position of 2 in preMirror[], we can find left and right subtrees.
  • Recursively construct the left subtree using the right part of the split range and the right subtree using the left part of the split range.
C++
#include <bits/stdc++.h>
using namespace std;

class Node {
public:
    int data;
    Node *left, *right;

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

// Recursive function to construct full binary tree
Node* constructBinaryTreeUtil(vector<int> &pre,
                              vector<int> &preMirror,
                              int &preIndex,
                              int l,
                              int h,
                              int n) {

    // Base case
    if (preIndex >= n || l > h)
        return nullptr;

    // Create root node
    Node* root = new Node(pre[preIndex++]);

    // If single element
    if (l == h)
        return root;

    // Find next preorder element in preMirror
    int i;
    for (i = l; i <= h; i++) {
        if (pre[preIndex] == preMirror[i])
            break;
    }

    // Build left and right subtrees
    if (i <= h) {

        root->left = constructBinaryTreeUtil(pre, preMirror,
                                            preIndex, i, h, n);

        root->right = constructBinaryTreeUtil(pre, preMirror,
                                             preIndex, l + 1, i - 1, n);
    }

    return root;
}

Node* constructBinaryTree(vector<int> &pre, vector<int> &preMirror) {

    int n = pre.size();
    int preIndex = 0;

    return constructBinaryTreeUtil(pre, preMirror,
                                   preIndex, 0, n - 1, n);
}

// Inorder traversal
void printInorder(Node* root) {

    if (root == nullptr)
        return;

    printInorder(root->left);
    cout << root->data << " ";
    printInorder(root->right);
}

int main() {

    vector<int> pre = {1, 2, 4, 5, 3, 6, 7};
    vector<int> preMirror = {1, 3, 7, 6, 2, 5, 4};

    Node* root = constructBinaryTree(pre, preMirror);

    printInorder(root);

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

class Node {
    int data;
    Node left, right;

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

class GFG {

    // Recursive function to construct full binary tree
   public static Node constructBinaryTreeUtil(int[] pre,
                                 int[] preMirror,
                                 int[] preIndex,
                                 int l,
                                 int h,
                                 int n) {

        // Base case
        if (preIndex[0] >= n || l > h)
            return null;

        // Create root node
        Node root = new Node(pre[preIndex[0]++]);

        // If single element
        if (l == h)
            return root;

        // Find next preorder element in preMirror
        int i;
        for (i = l; i <= h; i++) {
            if (pre[preIndex[0]] == preMirror[i])
                break;
        }

        // Build subtrees
        if (i <= h) {

            root.left = constructBinaryTreeUtil(pre, preMirror, preIndex, i, h, n);
            root.right = constructBinaryTreeUtil(pre, preMirror, preIndex, l + 1, i - 1, n);
        }

        return root;
    }

    public static Node constructBinaryTree(int[] pre, int[] preMirror) {

        int n = pre.length;
        int[] preIndex = {0};

        return constructBinaryTreeUtil(pre, preMirror, preIndex, 0, n - 1, n);
    }

    // Inorder traversal
    public static void printInorder(Node root) {

        if (root == null)
            return;

        printInorder(root.left);
        System.out.print(root.data + " ");
        printInorder(root.right);
    }

    public static void main(String[] args) {

        int[] pre = {1, 2, 4, 5, 3, 6, 7};
        int[] preMirror = {1, 3, 7, 6, 2, 5, 4};

        Node root = constructBinaryTree(pre, preMirror);

        printInorder(root);
    }
}
Python
class Node:
    def __init__(self, x):
        self.data = x
        self.left = None
        self.right = None


# Recursive function to construct full binary tree
def constructBinaryTreeUtil(pre, preMirror, preIndex, l, h, n):

    # Base case
    if preIndex[0] >= n or l > h:
        return None

    # Create root node
    root = Node(pre[preIndex[0]])
    preIndex[0] += 1

    # If single element
    if l == h:
        return root

    # Find next preorder element in preMirror
    i = l
    while i <= h:
        if pre[preIndex[0]] == preMirror[i]:
            break
        i += 1

    # Build subtrees
    if i <= h:

        root.left = constructBinaryTreeUtil(pre, preMirror, preIndex, i, h, n)

        root.right = constructBinaryTreeUtil(pre, preMirror, preIndex, l + 1, i - 1, n)

    return root


# Wrapper function
def constructBinaryTree(pre, preMirror):

    n = len(pre)
    preIndex = [0]

    return constructBinaryTreeUtil(pre, preMirror, preIndex, 0, n - 1, n)


# Inorder traversal
def inorder(root):
    if not root:
        return
    inorder(root.left)
    print(root.data, end=" ")
    inorder(root.right)

if __name__ == "__main__":

    pre = [1, 2, 4, 5, 3, 6, 7]
    preMirror = [1, 3, 7, 6, 2, 5, 4]

    root = constructBinaryTree(pre, preMirror)

    inorder(root)
C#
using System;

class Node {
    public int data;
    public Node left, right;

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

// Recursive function to construct full binary tree
class GFG
{
    static Node constructBinaryTreeUtil(int[] pre,
                                        int[] preMirror,
                                        int[] preIndex,
                                        int l,
                                        int h,
                                        int n) {

        // Base case
        if (preIndex[0] >= n || l > h)
            return null;

        // Create root node
        Node root = new Node(pre[preIndex[0]]);
        preIndex[0]++;

        // If single element
        if (l == h)
            return root;

        // Find next preorder element in preMirror
        int i = l;
        for (; i <= h; i++) {
            if (pre[preIndex[0]] == preMirror[i])
                break;
        }

        // Build subtrees
        if (i <= h) {

            root.left = constructBinaryTreeUtil(pre, preMirror, preIndex, i, h, n);

            root.right = constructBinaryTreeUtil(pre, preMirror, preIndex, l + 1, i - 1, n);
        }

        return root;
    }

    static Node constructBinaryTree(int[] pre, int[] preMirror) {

        int n = pre.Length;
        int[] preIndex = new int[] { 0 };

        return constructBinaryTreeUtil(pre, preMirror, preIndex, 0, n - 1, n);
    }

    static void inorder(Node root) {
        if (root == null) return;

        inorder(root.left);
        Console.Write(root.data + " ");
        inorder(root.right);
    }

    static void Main() {

        int[] pre = {1, 2, 4, 5, 3, 6, 7};
        int[] preMirror = {1, 3, 7, 6, 2, 5, 4};

        Node root = constructBinaryTree(pre, preMirror);

        inorder(root);
    }
}
JavaScript
class Node {
    constructor(x) {
        this.data = x;
        this.left = null;
        this.right = null;
    }
}

// Recursive function to construct full binary tree
function constructBinaryTreeUtil(pre, preMirror, preIndex, l, h, n) {

    // Base case
    if (preIndex[0] >= n || l > h)
        return null;

    // Create root node
    let root = new Node(pre[preIndex[0]]);
    preIndex[0]++;

    // If single element
    if (l === h)
        return root;

    // Find next preorder element in preMirror
    let i = l;
    while (i <= h) {
        if (pre[preIndex[0]] === preMirror[i])
            break;
        i++;
    }

    // Build subtrees
    if (i <= h) {

        root.left = constructBinaryTreeUtil(pre, preMirror, preIndex, i, h, n);

        root.right = constructBinaryTreeUtil(pre, preMirror, preIndex, l + 1, i - 1, n);
    }

    return root;
}

// Wrapper
function constructBinaryTree(pre, preMirror) {

    let n = pre.length;
    let preIndex = [0];

    return constructBinaryTreeUtil(pre, preMirror, preIndex, 0, n - 1, n);
}

// Inorder traversal
function inorder(root) {
    if (!root) return;
    inorder(root.left);
    process.stdout.write(root.data + " ");
    inorder(root.right);
}

// Drive code

    let pre = [1, 2, 4, 5, 3, 6, 7];
    let preMirror = [1, 3, 7, 6, 2, 5, 4];

    let root = constructBinaryTree(pre, preMirror);

    inorder(root);

Output
4 2 5 1 6 3 7 

[Expected Approach] Hash Map or Dictionary Optimization – O(n) Time and O(n) Space

To optimize the above solution, we store the index of every element of preMirror[] in a Hash Map so that we can find the split position in O(1) time. This helps us quickly divide the current range into left and right subtrees and build the tree efficiently using recursion.

  • Store all elements of preMirror[] in a Hash Map with their indices for fast lookup.
  • Take the first element of pre[] as the root and maintain a pointer preIndex.
  • For the next element in pre[], use the Hash Map to directly find its index in preMirror[].
  • This index divides the current range into left subtree range and right subtree range.
  • Recursively construct the left subtree and right subtree using the same logic.

Let us consider: pre[] = {1, 2, 4, 5, 3, 6, 7} , preMirror[] = {1, 3, 7, 6, 2, 5, 4}

Step 1:

  • Root = 1 (first element of pre[])
  • Store indices of preMirror[] in HashMap: {1→0, 3→1, 7→2, 6→3, 2→4, 5→5, 4→6}

Step 2:

  • Next element in pre[] is 2
  • Using HashMap, index of 2 in preMirror[] = 4
  • This splits range into:
  • Left subtree range: [4 ... 6]
  • Right subtree range: [1 ... 3]

Step 3: Recursively build left and right subtrees using the same process.

The tree is successfully constructed, and its inorder traversal becomes: 4 2 5 1 6 3 7

C++
#include <bits/stdc++.h>
using namespace std;

// Definition of Node
class Node {
public:
    int data;
    Node *left, *right;

    Node(int x) {
        data = x;
        left = right = NULL;
    }
};

// Recursive function to construct binary tree
Node* buildTree(vector<int>& pre, vector<int>& preMirror, int& preIndex, int left,
                int right, unordered_map<int, int>& mp, int n) {

    // Base case
    if (preIndex >= n || left > right)
        return NULL;

    // Create current node
    Node* root = new Node(pre[preIndex++]);

    // If leaf node
    if (left == right)
        return root;

    // Find next preorder element index in preMirror
    int mirrorIndex = mp[pre[preIndex]];

    // Construct left and right subtree
    if (mirrorIndex >= left && mirrorIndex <= right) {

        // Construct left subtree
        root->left = buildTree(pre, preMirror, preIndex, mirrorIndex, right, mp, n);

        // Construct right subtree
        root->right =
            buildTree(pre, preMirror, preIndex, left + 1, mirrorIndex - 1, mp, n);
    }

    return root;
}

// Wrapper function to construct binary tree
Node* constructBinaryTree(vector<int>& pre, vector<int>& preMirror) {

    int n = pre.size();

    // Store indices of mirror preorder traversal
    unordered_map<int, int> mp;
    for (int i = 0; i < n; i++) {
        mp[preMirror[i]] = i;
    }

    int preIndex = 0;

    return buildTree(pre, preMirror, preIndex, 0, n - 1, mp, n);
}

// Inorder traversal
void inorder(Node* root) {
    if (!root) return;

    inorder(root->left);
    cout << root->data << " ";
    inorder(root->right);
}

int main() {

    vector<int> pre = {1, 2, 4, 5, 3, 6, 7};
    vector<int> preMirror = {1, 3, 7, 6, 2, 5, 4};

    Node* root = constructBinaryTree(pre, preMirror);

    inorder(root);

    return 0;
}
Java
// Definition of Node
class Node {
    int data;
    Node left, right;

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

public class GFG {

    // Recursive function to construct binary tree
    static Node buildTree(int[] pre, int[] preMirror, int[] preIndex,
                          int left, int right, HashMap<Integer, Integer> mp, int n) {

        // Base case
        if (preIndex[0] >= n || left > right)
            return null;

        // Create current node
        Node root = new Node(pre[preIndex[0]++]);

        // If leaf node
        if (left == right)
            return root;

        // Find next preorder element index in preMirror
        int mirrorIndex = mp.get(pre[preIndex[0]]);

        // Construct left and right subtree
        if (mirrorIndex >= left && mirrorIndex <= right) {

            // Construct left subtree
            root.left = buildTree(pre, preMirror, preIndex, mirrorIndex, right, mp, n);

            // Construct right subtree
            root.right = buildTree(pre, preMirror, preIndex, left + 1, mirrorIndex - 1, mp, n);
        }

        return root;
    }

    // Wrapper function to construct binary tree
    static Node constructBinaryTree(int[] pre, int[] preMirror) {

        int n = pre.length;

        // Store indices of mirror preorder traversal
        HashMap<Integer, Integer> mp = new HashMap<>();

        for (int i = 0; i < n; i++) {
            mp.put(preMirror[i], i);
        }

        int[] preIndex = new int[]{0};

        return buildTree(pre, preMirror, preIndex, 0, n - 1, mp, n);
    }

    // Inorder traversal
    static void inorder(Node root) {
        if (root == null)
            return;

        inorder(root.left);
        System.out.print(root.data + " ");
        inorder(root.right);
    }

    // main function
    public static void main(String[] args) {

        int[] pre = {1, 2, 4, 5, 3, 6, 7};
        int[] preMirror = {1, 3, 7, 6, 2, 5, 4};

        Node root = constructBinaryTree(pre, preMirror);

        inorder(root);
    }
}
Python
# Definition of Node
class Node:
    def __init__(self, x):
        self.data = x
        self.left = None
        self.right = None


# Recursive function to construct binary tree
def buildTree(pre, preMirror, preIndex, left, right, mp, n):

    # Base case
    if preIndex[0] >= n or left > right:
        return None

    # Create current node
    root = Node(pre[preIndex[0]])
    preIndex[0] += 1

    # If leaf node
    if left == right:
        return root

    # Find next preorder element index in preMirror
    mirrorIndex = mp[pre[preIndex[0]]]

    # Construct left and right subtree
    if mirrorIndex >= left and mirrorIndex <= right:

        # Construct left subtree
        root.left = buildTree(pre, preMirror, preIndex, mirrorIndex, right, mp, n)

        # Construct right subtree
        root.right = buildTree(pre, preMirror, preIndex, left + 1, mirrorIndex - 1, mp, n)

    return root


# Wrapper function to construct binary tree
def constructBinaryTree(pre, preMirror):

    n = len(pre)

    # Store indices of mirror preorder traversal
    mp = {}
    for i in range(n):
        mp[preMirror[i]] = i

    preIndex = [0]

    return buildTree(pre, preMirror, preIndex, 0, n - 1, mp, n)


# Inorder traversal
def inorder(root):
    if not root:
        return

    inorder(root.left)
    print(root.data, end=" ")
    inorder(root.right)

if __name__ == "__main__":

    pre = [1, 2, 4, 5, 3, 6, 7]
    preMirror = [1, 3, 7, 6, 2, 5, 4]

    root = constructBinaryTree(pre, preMirror)

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

// Definition of Node
class Node {
    public int data;
    public Node left, right;

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

class GFG {

    // Recursive function to construct binary tree
    static Node buildTree(int[] pre, int[] preMirror, int[] preIndex,
                          int left, int right, Dictionary<int, int> mp, int n) {

        // Base case
        if (preIndex[0] >= n || left > right)
            return null;

        // Create current node
        Node root = new Node(pre[preIndex[0]++]);

        // If leaf node
        if (left == right)
            return root;

        // Find next preorder element index in preMirror
        int mirrorIndex = mp[pre[preIndex[0]]];

        // Construct left and right subtree
        if (mirrorIndex >= left && mirrorIndex <= right) {

            // Construct left subtree
            root.left = buildTree(pre, preMirror, preIndex, mirrorIndex, right, mp, n);

            // Construct right subtree
            root.right = buildTree(pre, preMirror, preIndex, left + 1, mirrorIndex - 1, mp, n);
        }

        return root;
    }

    // Wrapper function to construct binary tree
    static Node constructBinaryTree(int[] pre, int[] preMirror) {

        int n = pre.Length;

        // Store indices of mirror preorder traversal
        Dictionary<int, int> mp = new Dictionary<int, int>();
        for (int i = 0; i < n; i++) {
            mp[preMirror[i]] = i;
        }

        int[] preIndex = new int[] { 0 };

        return buildTree(pre, preMirror, preIndex, 0, n - 1, mp, n);
    }

    // Inorder traversal
    static void inorder(Node root) {
        if (root == null) return;

        inorder(root.left);
        Console.Write(root.data + " ");
        inorder(root.right);
    }

    // main
    static void Main() {

        int[] pre = {1, 2, 4, 5, 3, 6, 7};
        int[] preMirror = {1, 3, 7, 6, 2, 5, 4};

        Node root = constructBinaryTree(pre, preMirror);

        inorder(root);
    }
}
JavaScript
// Definition of Node
class Node {
    constructor(x) {
        this.data = x;
        this.left = null;
        this.right = null;
    }
}

// Recursive function to construct binary tree
function buildTree(pre, preMirror, preIndex, left, right, mp, n) {

    // Base case
    if (preIndex[0] >= n || left > right)
        return null;

    // Create current node
    let root = new Node(pre[preIndex[0]++]);

    // If leaf node
    if (left === right)
        return root;

    // Find next preorder element index in preMirror
    let mirrorIndex = mp.get(pre[preIndex[0]]);

    // Construct left and right subtree
    if (mirrorIndex >= left && mirrorIndex <= right) {

        // Construct left subtree
        root.left = buildTree(pre, preMirror, preIndex, mirrorIndex, right, mp, n);

        // Construct right subtree
        root.right = buildTree(pre, preMirror, preIndex, left + 1, mirrorIndex - 1, mp, n);
    }

    return root;
}

// Wrapper function to construct binary tree
function constructBinaryTree(pre, preMirror) {

    let n = pre.length;

    // Store indices of mirror preorder traversal
    let mp = new Map();
    for (let i = 0; i < n; i++) {
        mp.set(preMirror[i], i);
    }

    let preIndex = [0];

    return buildTree(pre, preMirror, preIndex, 0, n - 1, mp, n);
}

// Inorder traversal
function inorder(root) {
    if (!root) return;

    inorder(root.left);
    process.stdout.write(root.data + " ");
    inorder(root.right);
}

// Drive code

    let pre = [1, 2, 4, 5, 3, 6, 7];
    let preMirror = [1, 3, 7, 6, 2, 5, 4];

    let root = constructBinaryTree(pre, preMirror);

    inorder(root);

Output
4 2 5 1 6 3 7 
Comment