Related Articles
Generate original permutation from given array of inversions
• Difficulty Level : Medium
• Last Updated : 12 Nov, 2020

Given an array arr[] of size N, where arr[i] denotes the number of elements on the left that are greater than the ith element in the original permutation. The task is to find the original permutation of [1, N] for which given inversion array arr[] holds valid.

Examples:

Input: arr[] = {0, 1, 1, 0, 3}
Output: 4 1 3 5 2
Explanation:
The original permutation is ans[] = {4, 1, 3, 5, 2}
ans = 4.
ans = 1. Since {4} exists on its left, which exceeds 1, arr = 1 holds valid.
ans = 3. Since {4} exists on its left, which exceeds 3, arr = 1 holds valid.
ans = 5. Since no elements on its left exceeds 5, arr = 0 holds valid.
ans = 2. Since {4, 3, 5} exists on its left, which exceeds 2, arr = 3 holds valid.

Input: arr[] = {0, 1, 2}
Output: 3 2 1

Naive Approach: The simplest approach is to generate all the permutations of N number and for each permutation, check if its elements satisfy the inversions given by the array arr[]. If such permutation is found, print it.

Time Complexity: O(N!)
Auxiliary Space: O(N)

Efficient Approach: To optimize the above approach, the idea is to use a Segment Tree. Follow the below steps to solve the problem:

1. Build a segment tree of size N and initialize all leaf nodes with value 1.
2. Traverse the given array from right to left. For example, if the current index is N – 1, i.e, none of the elements are visited. So, the arr[i] is the number of elements that should be greater than the element which has to be at this position. So, the answer for this element is the (N – arr[N – 1])th element in the segment tree corresponds to that element. After that, mark that element as 0 to avoid its counting again.
3. Similarly, find (i + 1 – arr[i])th element in the segment tree, for each i from (N – 1) to 0.
4. After finding the answer for arr[i], let it be temp, store it in some array ans[], and update the node having index temp with 0.
5. Finally, print the answer array ans[] in reversed order as the original permutation.

Below is the implementation of the above approach:

## C++

 `// C++ program for the above approach` `#include ``using` `namespace` `std;``const` `int` `MAXX = 100;` `// Declaring segment tree``int` `st[4 * MAXX];` `// Function to initialize segment tree``// with leaves filled with ones``void` `build(``int` `x, ``int` `lx, ``int` `rx)``{``    ``// Base Case``    ``if` `(rx - lx == 1) {``        ``st[x] = 1;``        ``return``;``    ``}` `    ``// Split into two halves``    ``int` `m = (lx + rx) / 2;` `    ``// Build the left subtree``    ``build(x * 2 + 1, lx, m);` `    ``// Build the right subtree``    ``build(x * 2 + 2, m, rx);` `    ``// Combining both left and right``    ``// subtree to parent node``    ``st[x] = st[x * 2 + 1]``            ``+ st[x * 2 + 2];` `    ``return``;``}` `// Function to make index x to 0``// and then update segment tree``void` `update(``int` `i, ``int` `x,``            ``int` `lx, ``int` `rx)``{``    ``// Base Case``    ``if` `(rx - lx == 1) {``        ``st[x] = 0;``        ``return``;``    ``}` `    ``// Split into two halves``    ``int` `m = (lx + rx) / 2;` `    ``// Update Query``    ``if` `(i < m)``        ``update(i, x * 2 + 1, lx, m);``    ``else``        ``update(i, x * 2 + 2, m, rx);` `    ``// Combining both left and right``    ``// subtree to parent node``    ``st[x] = st[x * 2 + 1]``            ``+ st[x * 2 + 2];` `    ``return``;``}` `// Function to find the Kth element``int` `getans(``int` `x, ``int` `lx, ``int` `rx,``           ``int` `k, ``int` `n)``{``    ``// Base Condtiion``    ``if` `(rx - lx == 1) {``        ``if` `(st[x] == k)``            ``return` `lx;``        ``return` `n;``    ``}` `    ``// Split into two halves``    ``int` `m = (lx + rx) / 2;` `    ``// Check if kth one is in left subtree``    ``// or right subtree of current node``    ``if` `(st[x * 2 + 1] >= k)``        ``return` `getans(x * 2 + 1,``                      ``lx, m, k, n);``    ``else``        ``return` `getans(x * 2 + 2, m,``                      ``rx, k - st[x * 2 + 1],``                      ``n);``}` `// Function to generate the original``// permutation``void` `getPermutation(``int` `inv[], ``int` `n)``{``    ``// Build segment tree``    ``build(0, 0, n);` `    ``// Stores the original permutation``    ``vector<``int``> ans;` `    ``for` `(``int` `i = n - 1; i >= 0; i--) {` `        ``// Find kth one``        ``int` `temp = getans(0, 0, n,``                          ``st - inv[i], n);` `        ``// Answer for arr[i]``        ``ans.push_back(temp + 1);` `        ``// Setting found value back to 0``        ``update(max(0, temp), 0, 0, n);``    ``}` `    ``// Print the permutation``    ``for` `(``int` `i = n - 1; i >= 0; i--)``        ``cout << ans[i] << ``" "``;` `    ``return``;``}` `// Driver Code``int` `main()``{``    ``// Given array``    ``int` `inv[] = { 0, 1, 1, 0, 3 };` `    ``// Length of the given array``    ``int` `N = ``sizeof``(inv) / ``sizeof``(inv);` `    ``// Function Call``    ``getPermutation(inv, N);` `    ``return` `0;``}`

## Java

 `// Java program for the above approach``import` `java.util.*;` `class` `GFG{`` ` `static` `int` `MAXX = ``100``;` `// Declaring segment tree``static` `int` `[]st = ``new` `int``[``4` `* MAXX];` `// Function to initialize segment tree``// with leaves filled with ones``static` `void` `build(``int` `x, ``int` `lx, ``int` `rx)``{``    ` `    ``// Base Case``    ``if` `(rx - lx == ``1``)``    ``{``        ``st[x] = ``1``;``        ``return``;``    ``}` `    ``// Split into two halves``    ``int` `m = (lx + rx) / ``2``;` `    ``// Build the left subtree``    ``build(x * ``2` `+ ``1``, lx, m);` `    ``// Build the right subtree``    ``build(x * ``2` `+ ``2``, m, rx);` `    ``// Combining both left and right``    ``// subtree to parent node``    ``st[x] = st[x * ``2` `+ ``1``] + st[x * ``2` `+ ``2``];` `    ``return``;``}` `// Function to make index x to 0``// and then update segment tree``static` `void` `update(``int` `i, ``int` `x,``                   ``int` `lx, ``int` `rx)``{``    ` `    ``// Base Case``    ``if` `(rx - lx == ``1``)``    ``{``        ``st[x] = ``0``;``        ``return``;``    ``}` `    ``// Split into two halves``    ``int` `m = (lx + rx) / ``2``;` `    ``// Update Query``    ``if` `(i < m)``        ``update(i, x * ``2` `+ ``1``, lx, m);``    ``else``        ``update(i, x * ``2` `+ ``2``, m, rx);` `    ``// Combining both left and right``    ``// subtree to parent node``    ``st[x] = st[x * ``2` `+ ``1``] + st[x * ``2` `+ ``2``];` `    ``return``;``}` `// Function to find the Kth element``static` `int` `getans(``int` `x, ``int` `lx, ``int` `rx,``                  ``int` `k, ``int` `n)``{``    ` `    ``// Base Condtiion``    ``if` `(rx - lx == ``1``)``    ``{``        ``if` `(st[x] == k)``            ``return` `lx;``            ` `        ``return` `n;``    ``}` `    ``// Split into two halves``    ``int` `m = (lx + rx) / ``2``;` `    ``// Check if kth one is in left subtree``    ``// or right subtree of current node``    ``if` `(st[x * ``2` `+ ``1``] >= k)``        ``return` `getans(x * ``2` `+ ``1``,``                      ``lx, m, k, n);``    ``else``        ``return` `getans(x * ``2` `+ ``2``, m, rx,``               ``k - st[x * ``2` `+ ``1``], n);``}` `// Function to generate the original``// permutation``static` `void` `getPermutation(``int` `inv[], ``int` `n)``{``    ` `    ``// Build segment tree``    ``build(``0``, ``0``, n);` `    ``// Stores the original permutation``    ``Vector ans = ``new` `Vector();` `    ``for``(``int` `i = n - ``1``; i >= ``0``; i--)``    ``{``        ` `        ``// Find kth one``        ``int` `temp = getans(``0``, ``0``, n,``                          ``st[``0``] - inv[i], n);` `        ``// Answer for arr[i]``        ``ans.add(temp + ``1``);` `        ``// Setting found value back to 0``        ``update(Math.max(``0``, temp), ``0``, ``0``, n);``    ``}` `    ``// Print the permutation``    ``for``(``int` `i = n - ``1``; i >= ``0``; i--)``        ``System.out.print(ans.get(i) + ``" "``);` `    ``return``;``}` `// Driver Code``public` `static` `void` `main(String args[])``{``    ` `    ``// Given array``    ``int` `inv[] = { ``0``, ``1``, ``1``, ``0``, ``3` `};` `    ``// Length of the given array``    ``int` `N = inv.length;` `    ``// Function Call``    ``getPermutation(inv, N);``}``}` `// This code is contributed by SURENDRA_GANGWAR`

## Python3

 `# Python3 program for the above approach``MAXX ``=` `100` `# Declaring segment tree``st ``=` `[``0``] ``*` `(``4` `*` `MAXX)` `# Function to initialize segment tree``# with leaves filled with ones``def` `build(x, lx, rx):``    ` `    ``# Base Case``    ``if` `(rx ``-` `lx ``=``=` `1``):``        ``st[x] ``=` `1``        ``return` `    ``# Split into two halves``    ``m ``=` `(lx ``+` `rx) ``/``/` `2` `    ``# Build the left subtree``    ``build(x ``*` `2` `+` `1``, lx, m)` `    ``# Build the right subtree``    ``build(x ``*` `2` `+` `2``, m, rx)` `    ``# Combining both left and right``    ``# subtree to parent node``    ``st[x] ``=` `st[x ``*` `2` `+` `1``] ``+` `st[x ``*` `2` `+` `2``]` `    ``return` `# Function to make index x to 0``# and then update segment tree``def` `update(i, x, lx, rx):``    ` `    ``# Base Case``    ``if` `(rx ``-` `lx ``=``=` `1``):``        ``st[x] ``=` `0``        ``return` `    ``# Split into two halves``    ``m ``=` `(lx ``+` `rx) ``/``/` `2` `    ``# Update Query``    ``if` `(i < m):``        ``update(i, x ``*` `2` `+` `1``, lx, m)``    ``else``:``        ``update(i, x ``*` `2` `+` `2``, m, rx)` `    ``# Combining both left and right``    ``# subtree to parent node``    ``st[x] ``=` `st[x ``*` `2` `+` `1``] ``+` `st[x ``*` `2` `+` `2``]` `    ``return` `# Function to find the Kth element``def` `getans(x, lx, rx, k, n):``    ` `    ``# Base Condtiion``    ``if` `(rx ``-` `lx ``=``=` `1``):``        ``if` `(st[x] ``=``=` `k):``            ``return` `lx``            ` `        ``return` `n` `    ``# Split into two halves``    ``m ``=` `(lx ``+` `rx) ``/``/` `2` `    ``# Check if kth one is in left subtree``    ``# or right subtree of current node``    ``if` `(st[x ``*` `2` `+` `1``] >``=` `k):``        ``return` `getans(x ``*` `2` `+` `1``, lx, m, k, n)``    ``else``:``        ``return` `getans(x ``*` `2` `+` `2``, m, rx,``               ``k ``-` `st[x ``*` `2` `+` `1``], n)` `# Function to generate the original``# permutation``def` `getPermutation(inv, n):``    ` `    ``# Build segment tree``    ``build(``0``, ``0``, n)` `    ``# Stores the original permutation``    ``ans ``=` `[]` `    ``for` `i ``in` `range``(n ``-` `1``, ``-``1``, ``-``1``):``        ` `        ``# Find kth one``        ``temp ``=` `getans(``0``, ``0``, n, st[``0``] ``-` `inv[i], n)` `        ``# Answer for arr[i]``        ``ans.append(temp ``+` `1``)` `        ``# Setting found value back to 0``        ``update(``max``(``0``, temp), ``0``, ``0``, n)` `    ``# Print the permutation``    ``for` `i ``in` `range``(n ``-` `1``, ``-``1``, ``-``1``):``        ``print``(ans[i], end ``=` `" "``)` `    ``return` `# Driver Code``if` `__name__ ``=``=` `'__main__'``:``    ` `    ``# Given array``    ``inv ``=` `[ ``0``, ``1``, ``1``, ``0``, ``3` `]` `    ``# Length of the given array``    ``N ``=` `len``(inv)` `    ``# Function Call``    ``getPermutation(inv, N)` `# This code is contributed by mohit kumar 29`

## C#

 `// C# program for the above approach``using` `System;``using` `System.Collections.Generic;` `class` `GFG{`` ` `static` `int` `MAXX = 100;` `// Declaring segment tree``static` `int` `[]st = ``new` `int``[4 * MAXX];` `// Function to initialize segment tree``// with leaves filled with ones``static` `void` `build(``int` `x, ``int` `lx, ``int` `rx)``{``    ` `    ``// Base Case``    ``if` `(rx - lx == 1)``    ``{``        ``st[x] = 1;``        ``return``;``    ``}` `    ``// Split into two halves``    ``int` `m = (lx + rx) / 2;` `    ``// Build the left subtree``    ``build(x * 2 + 1, lx, m);` `    ``// Build the right subtree``    ``build(x * 2 + 2, m, rx);` `    ``// Combining both left and right``    ``// subtree to parent node``    ``st[x] = st[x * 2 + 1] + st[x * 2 + 2];` `    ``return``;``}` `// Function to make index x to 0``// and then update segment tree``static` `void` `update(``int` `i, ``int` `x,``                   ``int` `lx, ``int` `rx)``{``    ` `    ``// Base Case``    ``if` `(rx - lx == 1)``    ``{``        ``st[x] = 0;``        ``return``;``    ``}` `    ``// Split into two halves``    ``int` `m = (lx + rx) / 2;` `    ``// Update Query``    ``if` `(i < m)``        ``update(i, x * 2 + 1, lx, m);``    ``else``        ``update(i, x * 2 + 2, m, rx);` `    ``// Combining both left and right``    ``// subtree to parent node``    ``st[x] = st[x * 2 + 1] + st[x * 2 + 2];` `    ``return``;``}` `// Function to find the Kth element``static` `int` `getans(``int` `x, ``int` `lx, ``int` `rx,``                  ``int` `k, ``int` `n)``{``    ` `    ``// Base Condtiion``    ``if` `(rx - lx == 1)``    ``{``        ``if` `(st[x] == k)``            ``return` `lx;``            ` `        ``return` `n;``    ``}` `    ``// Split into two halves``    ``int` `m = (lx + rx) / 2;` `    ``// Check if kth one is in left subtree``    ``// or right subtree of current node``    ``if` `(st[x * 2 + 1] >= k)``        ``return` `getans(x * 2 + 1,``                      ``lx, m, k, n);``    ``else``        ``return` `getans(x * 2 + 2, m, rx,``               ``k - st[x * 2 + 1], n);``}` `// Function to generate the original``// permutation``static` `void` `getPermutation(``int` `[]inv, ``int` `n)``{``    ` `    ``// Build segment tree``    ``build(0, 0, n);` `    ``// Stores the original permutation``    ``List<``int``> ans = ``new` `List<``int``>();` `    ``for``(``int` `i = n - 1; i >= 0; i--)``    ``{``        ` `        ``// Find kth one``        ``int` `temp = getans(0, 0, n,``                          ``st - inv[i], n);` `        ``// Answer for arr[i]``        ``ans.Add(temp + 1);` `        ``// Setting found value back to 0``        ``update(Math.Max(0, temp), 0, 0, n);``    ``}` `    ``// Print the permutation``    ``for``(``int` `i = n - 1; i >= 0; i--)``        ``Console.Write(ans[i] + ``" "``);` `    ``return``;``}` `// Driver Code``public` `static` `void` `Main(String []args)``{``    ` `    ``// Given array``    ``int` `[]inv = { 0, 1, 1, 0, 3 };` `    ``// Length of the given array``    ``int` `N = inv.Length;` `    ``// Function Call``    ``getPermutation(inv, N);``}``}` `// This code is contributed by Amit Katiyar`
Output:
```4 1 3 5 2

```

Time Complexity: O(N*log N)
Auxiliary Space: O(N)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

My Personal Notes arrow_drop_up