GFG App
Open App
Browser
Continue

# Generate lexicographically smallest Permutation of 1 to N where elements follow given relation

Given an integer N and an array arr[] of M pairs of type (Ai, Bi), the task is to generate the lexicographically smallest possible permutation of 1 to N such that every Ai, occurs before every Bi.

Examples:

Input: N = 4, arr[] = { {2, 1}, {3, 4}, {2, 4} }
Output: 2 1 3 4
Explanation: The following five permutations P satisfy the condition:
(2, 1, 3, 4), (2, 3, 1, 4), (2, 3, 4, 1), (3, 2, 1, 4), (3, 2, 4, 1).
The lexicographically smallest among them is (2, 1, 3, 4).

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

Approach: The problem can be solved using the concept of Graph based on the following idea:

Consider a N vertex graph where there is an directed edge from A to B if A occurs before B in the permutation.

• So the target is to find a ordering such that any vertex occurs in the permutation after all its predecessors (the vertices which have edges directed to this one) have occurred in the permutation.
• While doing so, move from the least value to the maximum possible value for getting the lexicographically smallest permutation.

This can be done with the help of topological sorting.

• The topological sort will start from the vertices having indegree 0 and in sequence of smaller to greater value.
• After the topological sorting is over, if any vertex is still not included in the permutation, then no such permutation is possible.

Follow the below steps to solve the problem:

• Initialize one vector (say ans) to store the resulting permutation.
• Visit the M pairs and create directed edges from the first value of arr[i] to the second value of arr[i]. Also, increase the indegree of the second value of arr[i] by 1.
• Now find all the elements with indegree 0, push them in the resultant permutation in increasing order and start the topological sort.
• Add any vertex to the permutation when its indegree becomes 0.
• Maintain the lexicographic ordering while doing so, i.e. move from the lower value to the higher value.
• Take the help of min heap to perform the topological sorting:
•  Initially keep the vertices with indegree 0 in the heap.
• Then pop the least value vertex, append it to the ans, remove all its edges and decrease the indegree by 1 of all the vertices connected to it.
• If the indegree of any vertex becomes 0 in this process, push that into the heap.
• Return ans as the final required permutation.

Below is the implementation of the above approach.

## C++

 `// C++ program to implement above approach`   `#include ` `using` `namespace` `std;`   `// Function to obtain the permutation` `vector<``int``> Calculate(``int` `n, ``int` `m,` `                      ``vector > arr)` `{` `    ``// Prepare an empty array ans` `    ``vector<``int``> ans;` `    ``vector<``int``> indegree(n);` `    ``vector > out(n);`   `    ``// Build the directed graph` `    ``for` `(``int` `i = 0; i < m; i++) {` `        ``int` `a = arr[i].first;` `        ``int` `b = arr[i].second;` `        ``a--;` `        ``b--;`   `        ``// Calculate indegree of every element` `        ``indegree[b] = indegree[b] + 1;`   `        ``// Store connection of each node` `        ``out[a].push_back(b);` `    ``}`   `    ``// Declaring the min heap` `    ``priority_queue<``int``, vector<``int``>,` `                   ``greater<``int``> >` `        ``heap;`   `    ``for` `(``int` `i = 0; i < n; ++i) {` `        ``if` `(indegree[i] == 0) {`   `            ``// Push elements in priority queue` `            ``// if indegree is 0` `            ``heap.push(i);` `        ``}` `    ``}`   `    ``// Run topological sort` `    ``while` `(!heap.empty()) {`   `        ``// Choose vertex with degree 0,` `        ``// denoted by i` `        ``int` `i = heap.top();` `        ``heap.pop();`   `        ``// Push i+1 to the tail of ans` `        ``ans.push_back(i + 1);`   `        ``// Remove i and edges going out from i` `        ``for` `(``int` `j : out[i]) {` `            ``indegree[j] -= 1;`   `            ``// In the process if any node's indegree` `            ``// becomes 0 then push the element` `            ``// to the priority queue` `            ``if` `(indegree[j] == 0) {` `                ``heap.push(j);` `            ``}` `        ``}` `    ``}`   `    ``// If size of ans is not n then` `    ``// output would is not possible` `    ``if` `(ans.size() != n) {` `        ``ans.clear();` `        ``ans.push_back(-1);` `    ``}` `    ``return` `ans;` `}`   `// Driver code` `int` `main()` `{` `    ``int` `N = 4, M = 3;` `    ``vector > arr` `        ``= { { 2, 1 }, { 3, 4 }, { 2, 4 } };`   `    ``// Function call` `    ``vector<``int``> res = Calculate(N, M, arr);` `    ``for` `(``int` `x : res)` `        ``cout << x << ``" "``;` `    ``return` `0;` `}`

## Java

 `// Java program to implement above approach` `import` `java.io.*;` `import` `java.util.*;`   `class` `GFG {` `    ``// Function to obtain the permutation` `    ``public` `static` `ArrayList Calculate(``int` `n, ``int` `m,` `                                               ``int` `arr[][])` `    ``{` `        ``// Prepare an empty array ans` `        ``ArrayList ans = ``new` `ArrayList();` `        ``int` `indegree[] = ``new` `int``[n];` `        ``ArrayList > out` `            ``= ``new` `ArrayList >(n);`   `        ``for` `(``int` `i = ``0``; i < n; i++) {` `            ``out.add(``new` `ArrayList());` `        ``}`   `        ``// Build the directed graph` `        ``for` `(``int` `i = ``0``; i < m; i++) {` `            ``int` `a = arr[i][``0``];` `            ``int` `b = arr[i][``1``];` `            ``a--;` `            ``b--;`   `            ``// Calculate indegree of every element` `            ``indegree[b] = indegree[b] + ``1``;`   `            ``// Store connection of each node` `            ``out.get(a).add(b);` `        ``}`   `        ``// Declaring the min heap` `        ``PriorityQueue heap = ``new` `PriorityQueue<>();` `        ``for` `(``int` `i = ``0``; i < n; ++i) {` `            ``if` `(indegree[i] == ``0``) {`   `                ``// Push elements in priority queue` `                ``// if indegree is 0` `                ``heap.add(i);` `            ``}` `        ``}`   `        ``// Run topological sort` `        ``while` `(!heap.isEmpty()) {`   `            ``// Choose vertex with degree 0,` `            ``// denoted by i` `            ``int` `i = heap.peek();` `            ``heap.poll();`   `            ``// Push i+1 to the tail of ans` `            ``ans.add(i + ``1``);`   `            ``// Remove i and edges going out from i` `            ``for` `(Integer j : out.get(i)) {` `                ``indegree[j] -= ``1``;`   `                ``// In the process if any node's indegree` `                ``// becomes 0 then push the element` `                ``// to the priority queue` `                ``if` `(indegree[j] == ``0``) {` `                    ``heap.add(j);` `                ``}` `            ``}` `        ``}`   `        ``// If size of ans is not n then` `        ``// output would is not possible` `        ``if` `(ans.size() != n) {` `            ``ans.clear();` `            ``ans.add(-``1``);` `        ``}` `        ``return` `ans;` `    ``}`   `    ``// Driver Code` `    ``public` `static` `void` `main(String[] args)` `    ``{` `        ``int` `N = ``4``, M = ``3``;` `        ``int` `arr[][] = { { ``2``, ``1` `}, { ``3``, ``4` `}, { ``2``, ``4` `} };`   `        ``// Function call` `        ``ArrayList res = Calculate(N, M, arr);` `        ``for` `(Integer x : res)` `            ``System.out.print(x + ``" "``);` `    ``}` `}`   `// This code is contributed by Rohit Pradhan`

## Python3

 `# Python program to implement above approach` `def` `Calculate(n, m, arr):` `  `  `    ``# Prepare an empty array ans` `    ``ans ``=` `[]` `    ``indegree ``=` `[``0``] ``*` `n` `    ``out ``=` `[[] ``for` `i ``in` `range``(n)]`   `    ``# Build the directed graph` `    ``for` `i ``in` `range``(m):` `        ``a ``=` `arr[i][``0``]` `        ``b ``=` `arr[i][``1``]` `        ``a ``-``=` `1` `        ``b ``-``=` `1`   `        ``# Calculate indegree of every element` `        ``indegree[b] ``+``=` `1`   `        ``# Store connection of each node` `        ``out[a].append(b)`   `    ``# Declaring the min heap` `    ``heap ``=` `[]`   `    ``for` `i ``in` `range``(n):` `        ``if` `indegree[i] ``=``=` `0``:`   `            ``# Push elements in priority queue` `            ``# if indegree is 0` `            ``heap.append(i)`   `    ``# Run topological sort` `    ``while` `heap:`   `        ``# Choose vertex with degree 0,` `        ``# denoted by i` `        ``i ``=` `heap.pop(``0``)`   `        ``# Push i+1 to the tail of ans` `        ``ans.append(i ``+` `1``)`   `        ``# Remove i and edges going out from i` `        ``for` `j ``in` `out[i]:` `            ``indegree[j] ``-``=` `1`   `            ``# In the process if any node's indegree` `            ``# becomes 0 then push the element` `            ``# to the priority queue` `            ``if` `indegree[j] ``=``=` `0``:` `                ``heap.append(j)`   `    ``# If size of ans is not n then` `    ``# output would is not possible` `    ``if` `len``(ans) !``=` `n:` `        ``ans ``=` `[``-``1``]`   `    ``return` `ans`   `# Driver code` `if` `__name__ ``=``=` `'__main__'``:` `    ``n ``=` `4` `    ``m ``=` `3` `    ``arr ``=` `[[``2``, ``1``], [``3``, ``4``], [``2``, ``4``]]` `    ``res ``=` `Calculate(n, m, arr)` `    ``print``(res)` `    `  `    ``# This code is contributed by abhinavprkash.`

## C#

 `// C# program to implement above approach` `using` `System;` `using` `System.Collections.Generic;`   `class` `GFG {` `    ``static` `List<``int``> Calculate(``int` `n, ``int` `m, ``int``[, ] arr)` `    ``{` `        ``// Prepare an empty array ans` `        ``List<``int``> ans = ``new` `List<``int``>();` `        ``int``[] indegree = ``new` `int``[n];` `        ``// for (int i = 0; i < n; i++)` `        ``//    indegree[i] = 0;` `        ``List > Out = ``new` `List >();` `        ``for` `(``var` `i = 0; i < n; i++)` `            ``Out.Add(``new` `List<``int``>());`   `        ``// Build the directed graph` `        ``for` `(``var` `i = 0; i < m; i++) {` `            ``var` `a = arr[i, 0];` `            ``var` `b = arr[i, 1];` `            ``a -= 1;` `            ``b -= 1;`   `            ``// Calculate indegree of every element` `            ``indegree[b] += 1;`   `            ``// Store connection of each node` `            ``Out[a].Add(b);` `        ``}`   `        ``// Declaring the min heap` `        ``List<``int``> heap = ``new` `List<``int``>();`   `        ``for` `(``var` `i = 0; i < n; i++) {` `            ``if` `(indegree[i] == 0) {` `                ``// Push elements in priority queue` `                ``// if indegree is 0` `                ``heap.Add(i);` `            ``}` `        ``}`   `        ``// Run topological sort` `        ``while` `(heap.Count > 0) {` `            ``heap.Sort();` `            ``// Choose vertex with degree 0,` `            ``// denoted by i` `            ``var` `i = heap[0];` `            ``heap.RemoveAt(0);`   `            ``// Push i+1 to the tail of ans` `            ``ans.Add(i + 1);`   `            ``// Remove i and edges going out from i` `            ``for` `(``var` `k = 0; k < Out[i].Count; k++) {` `                ``var` `j = Out[i][k];` `                ``indegree[j] -= 1;`   `                ``// In the process if any node's indegree` `                ``// becomes 0 then push the element` `                ``// to the priority queue` `                ``if` `(indegree[j] == 0)` `                    ``heap.Add(j);` `            ``}` `        ``}`   `        ``// If size of ans is not n then` `        ``// output would is not possible` `        ``if` `(ans.Count != n) {` `            ``ans.Clear();` `            ``ans.Add(-1);` `        ``}`   `        ``return` `ans;` `    ``}`   `    ``// Driver code` `    ``public` `static` `void` `Main(``string``[] args)` `    ``{` `        ``var` `n = 4;` `        ``var` `m = 3;` `        ``int``[, ] arr = { { 2, 1 }, { 3, 4 }, { 2, 4 } };` `        ``var` `res = Calculate(n, m, arr);` `        ``foreach``(``var` `i ``in` `res) Console.Write(i + ``" "``);` `    ``}` `}`   `// This code is contributed by phasing17`

## Javascript

 `//JavaScript program to implement above approach` `function` `Calculate(n, m, arr)` `{` `    ``// Prepare an empty array ans` `    ``var` `ans = [];` `    ``var` `indegree = ``new` `Array(n).fill(0);` `    ``var` `out = [];` `    ``for` `(``var` `i = 0; i < n; i++)` `        ``out.push([ ]);`   `    ``// Build the directed graph` `    ``for` `(``var` `i = 0; i < m; i++)` `    ``{` `        ``var` `a = arr[i][0];` `        ``var` `b = arr[i][1];` `        ``a -= 1;` `        ``b -= 1;` `    `  `        ``// Calculate indegree of every element` `        ``indegree[b] += 1;`   `        ``// Store connection of each node` `        ``out[a].push(b);` `    ``}`   `    ``// Declaring the min heap` `    ``var` `heap = [];` `    `  `    ``for` `(``var` `i = 0; i < n; i++)` `    ``{` `        ``if` `(indegree[i] == 0)` `        ``{` `            ``// Push elements in priority queue` `            ``// if indegree is 0` `            ``heap.push(i);` `        ``}` `    ``}` `    `  `    ``// Run topological sort` `    ``while` `(heap.length > 0)` `    ``{`   `        ``// Choose vertex with degree 0,` `        ``// denoted by i` `        ``var` `i = heap.shift();`   `        ``// Push i+1 to the tail of ans` `        ``ans.push(i + 1);`   `        `  `        ``// Remove i and edges going out from i` `        ``for` `(``var` `k = 0; k < out[i].length; k++)` `        ``{` `            ``var` `j = out[i][k];` `            ``indegree[j] -= 1;`   `            ``// In the process if any node's indegree` `            ``// becomes 0 then push the element` `            ``// to the priority queue` `            ``if` `(indegree[j] == 0)` `                ``heap.push(j);` `        ``}` `        `  `    ``}` `        `  `    ``// If size of ans is not n then` `    ``// output would is not possible` `    ``if` `(ans.length != n)` `        ``ans = [-1];` `        `    `    ``return` `ans;` `}`   `// Driver code` `var` `n = 4;` `var` `m = 3;` `var` `arr = [[2, 1], [3, 4], [2, 4]];` `var` `res = Calculate(n, m, arr);` `console.log(res);` `    `  `// This code is contributed by phasing17`

Output

`2 1 3 4 `

Time Complexity: O(N+M*log(M)) where N is the number of vertices and M is the number of edges in the directed graph.
Auxiliary Space: O(N+M)

My Personal Notes arrow_drop_up
Related Tutorials