Skip to content
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.

In case you wish to attend live classes with industry experts, please refer Geeks Classes Live

My Personal Notes arrow_drop_up