Find a permutation of N natural numbers with K inversions
Last Updated :
29 Nov, 2022
Given two integers N and K, the task is to find a permutation of first N natural numbers with exactly K inversions.
Examples :
Input: N = 5, K = 4
Output: 5 1 2 3 4
Explanation: In the above permutation P, the pairs (i, j) such that i < j and P[i] > P[j] are (0, 1), (0, 2), (0, 3), and (0, 4). Hence, the number of inversions in the above permutation is 4 which is the required value.
Input: N = 3, K = 4
Output: -1
Explanation: No possible permutation of first 3 natural numbers has exactly 4 inversions.
Approach: The given problem can be solved by a Greedy Approach. It can be observed that if the maximum element of an array of N elements is assigned at ith position, it will contribute (N – i) inversions. Using this observation, follow the below steps to solve the given problem:
- Check for the condition whether K > the maximum number of possible inversions (i.e, N*(N-1)/2). If true, return -1.
- Create a variable curr, which keeps track of the current maximum element of the array. Initially curr = N.
- Create an array p[], which keeps track of the current permutation.
- Iterate using a variable i in the range [1, N], and if K > (curr – i), assign curr to the current position of the array and subtract (curr – i) from K. Also, decrement the value of curr by 1.
- If K > (curr – i) is false, assign K+1 to the current index and assign the remaining integers in increasing order in the array p[].
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
void findPermutation( int n, int k)
{
int max_inv = (n * (n - 1)) / 2;
if (k > max_inv) {
cout << "-1" ;
return ;
}
int p[n + 1];
int curr = n;
int i = 1;
for (i = 1; i <= n; i++) {
if (k >= n - i) {
p[i] = curr;
curr--;
k -= (n - i);
}
else {
if (k == 0) {
i--;
}
else {
p[i] = k + 1;
}
p[i + 1] = 1;
for ( int j = i + 2; j <= n; j++) {
p[j] = p[j - 1] + 1;
if (p[i] == p[j]) {
p[j]++;
}
}
break ;
}
}
for ( int j = 1; j <= n; j++) {
cout << p[j] << " " ;
}
}
int main()
{
int n = 5;
int k = 4;
findPermutation(n, k);
return 0;
}
|
Java
import java.io.*;
class GFG {
static void findPermutation( int n, int k)
{
int max_inv = (n * (n - 1 )) / 2 ;
if (k > max_inv) {
System.out.println( "-1" );
return ;
}
int [] p = new int [n+ 1 ];
int curr = n;
int i = 1 ;
for (i = 1 ; i <= n; i++) {
if (k >= n - i) {
p[i] = curr;
curr--;
k -= (n - i);
}
else {
if (k == 0 ) {
i--;
}
else {
p[i] = k + 1 ;
}
p[i + 1 ] = 1 ;
for ( int j = i + 2 ; j <= n; j++) {
p[j] = p[j - 1 ] + 1 ;
if (p[i] == p[j]) {
p[j]++;
}
}
break ;
}
}
for ( int j = 1 ; j <= n; j++) {
System.out.print(p[j] + " " );
}
}
public static void main (String[] args) {
int n = 5 ;
int k = 4 ;
findPermutation(n, k);
}
}
|
Python3
def findPermutation(n, k):
max_inv = (n * (n - 1 )) / 2
if (k > max_inv):
print ( "-1" )
return
p = [ 0 for _ in range (n + 1 )]
curr = n
i = 1
for i in range ( 1 , n + 1 ):
if (k > = n - i):
p[i] = curr
curr - = 1
k - = (n - i)
else :
if (k = = 0 ):
i - = 1
else :
p[i] = k + 1
p[i + 1 ] = 1
for j in range (i + 2 , n + 1 ):
p[j] = p[j - 1 ] + 1
if (p[i] = = p[j]):
p[j] + = 1
break
for j in range ( 1 , n + 1 ):
print (p[j], end = " " )
if __name__ = = "__main__" :
n = 5
k = 4
findPermutation(n, k)
|
Javascript
<script>
const findPermutation = (n, k) => {
let max_inv = (n * (n - 1)) / 2;
if (k > max_inv) {
document.write( "-1" );
return ;
}
let p = new Array(n + 1).fill(0);
let curr = n;
let i = 1;
for (i = 1; i <= n; i++) {
if (k >= n - i) {
p[i] = curr;
curr--;
k -= (n - i);
}
else {
if (k == 0) {
i--;
}
else {
p[i] = k + 1;
}
p[i + 1] = 1;
for (let j = i + 2; j <= n; j++) {
p[j] = p[j - 1] + 1;
if (p[i] == p[j]) {
p[j]++;
}
}
break ;
}
}
for (let j = 1; j <= n; j++) {
document.write(`${p[j]} `);
}
}
let n = 5;
let k = 4;
findPermutation(n, k);
</script>
|
C#
using System;
public class GFG {
static void findPermutation( int n, int k)
{
int max_inv = (n * (n - 1)) / 2;
if (k > max_inv) {
Console.WriteLine( "-1" );
return ;
}
int [] p = new int [n+1];
int curr = n;
int i = 1;
for (i = 1; i <= n; i++) {
if (k >= n - i) {
p[i] = curr;
curr--;
k -= (n - i);
}
else {
if (k == 0) {
i--;
}
else {
p[i] = k + 1;
}
p[i + 1] = 1;
for ( int j = i + 2; j <= n; j++) {
p[j] = p[j - 1] + 1;
if (p[i] == p[j]) {
p[j]++;
}
}
break ;
}
}
for ( int j = 1; j <= n; j++) {
Console.Write(p[j] + " " );
}
}
public static void Main ( string [] args) {
int n = 5;
int k = 4;
findPermutation(n, k);
}
}
|
Time complexity: O(N)
Auxiliary Space: O(N)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...