📜  用 K 个求逆求 N 个自然数的排列

📅  最后修改于: 2022-05-13 01:57:50.805000             🧑  作者: Mango

用 K 个求逆求 N 个自然数的排列

给定两个整数NK ,任务是找到前N个自然数恰好有K个反转的排列。

例子 :

方法:给定的问题可以通过贪心方法来解决。可以观察到,如果将N个元素的数组的最大元素分配在第 i位置,它将贡献(N – i)次反转。使用此观察结果,请按照以下步骤解决给定问题:

  • 检查条件是否K > 可能的最大反转次数(即 N*(N-1)/2)。如果为真,则返回-1
  • 创建一个变量curr ,它跟踪数组的当前最大元素。最初curr = N
  • 创建一个数组p[] ,它跟踪当前的排列。
  • 使用 [1, N] 范围内的变量i进行迭代,如果K > (curr – i) ,则将 curr 分配给数组的当前位置并从K中减去(curr – i) 。此外,将curr的值减 1。
  • 如果K > (curr – i)为假,则将K+1分配给当前索引,并在数组p[]中按升序分配剩余的整数。

下面是上述方法的实现:

C++
// C++ program of the above approach
#include 
using namespace std;
 
// Function to fint the permutation of
// N natural numbers with k inversions
void findPermutation(int n, int k)
{
    // Stores the maximum number of inversions
    int max_inv = (n * (n - 1)) / 2;
 
    // If required inversions are more that max
    if (k > max_inv) {
        cout << "-1";
        return;
    }
 
    // Stores the final permutation
    int p[n + 1];
 
    // Keep track of the current max element
    // in the permutation
    int curr = n;
    int i = 1;
 
    // Loop to iterate through the array
    for (i = 1; i <= n; i++) {
 
        // Set current element as ith element
        // in order to increase n-i inversions
        // in the given permutation
        if (k >= n - i) {
            p[i] = curr;
            curr--;
            k -= (n - i);
        }
 
        // Otherwise set (k+1) element at ith index
        // ans assign the remaining indices
        else {
            // If the remaining inversion count is
            // greater than 0
            if (k == 0) {
                i--;
            }
            else {
                p[i] = k + 1;
            }
 
            // Set the next index as 1
            p[i + 1] = 1;
 
            // Loop to assign the remaining indices
            for (int j = i + 2; j <= n; j++) {
                p[j] = p[j - 1] + 1;
 
                // If current element already occured
                if (p[i] == p[j]) {
                    p[j]++;
                }
            }
            break;
        }
    }
 
    // Print Answer
    for (int j = 1; j <= n; j++) {
        cout << p[j] << " ";
    }
}
 
// Driver code
int main()
{
    int n = 5;
    int k = 4;
 
    findPermutation(n, k);
 
    return 0;
}


Java
// Java program for the above approach
import java.io.*;
 
class GFG {
   
// Function to fint the permutation of
// N natural numbers with k inversions
static void findPermutation(int n, int k)
{
   
    // Stores the maximum number of inversions
    int max_inv = (n * (n - 1)) / 2;
 
    // If required inversions are more that max
    if (k > max_inv) {
         System.out.println("-1");
        return;
    }
 
    // Stores the final permutation
    int [] p = new int[n+1];
 
    // Keep track of the current max element
    // in the permutation
    int curr = n;
    int i = 1;
 
    // Loop to iterate through the array
    for (i = 1; i <= n; i++) {
 
        // Set current element as ith element
        // in order to increase n-i inversions
        // in the given permutation
        if (k >= n - i) {
            p[i] = curr;
            curr--;
            k -= (n - i);
        }
 
        // Otherwise set (k+1) element at ith index
        // ans assign the remaining indices
        else {
            // If the remaining inversion count is
            // greater than 0
            if (k == 0) {
                i--;
            }
            else {
                p[i] = k + 1;
            }
 
            // Set the next index as 1
            p[i + 1] = 1;
 
            // Loop to assign the remaining indices
            for (int j = i + 2; j <= n; j++) {
                p[j] = p[j - 1] + 1;
 
                // If current element already occured
                if (p[i] == p[j]) {
                    p[j]++;
                }
            }
            break;
        }
    }
 
    // Print Answer
    for (int j = 1; j <= n; j++) {
         System.out.print(p[j] + " ");
    }
}
 
// Driver code
    public static void main (String[] args) {
       int n = 5;
    int k = 4;
 
    findPermutation(n, k);
    }
}
 
// This code is contributed by Potta Lokesh


Python3
# python program of the above approach
 
# Function to fint the permutation of
# N natural numbers with k inversions
def findPermutation(n, k):
 
    # Stores the maximum number of inversions
    max_inv = (n * (n - 1)) / 2
 
    # If required inversions are more that max
    if (k > max_inv):
        print("-1")
        return
 
    # Stores the final permutation
    p = [0 for _ in range(n + 1)]
 
    # Keep track of the current max element
    # in the permutation
    curr = n
    i = 1
 
    # Loop to iterate through the array
    for i in range(1, n+1):
 
        # Set current element as ith element
        # in order to increase n-i inversions
        # in the given permutation
        if (k >= n - i):
            p[i] = curr
            curr -= 1
            k -= (n - i)
 
        # Otherwise set (k+1) element at ith index
        # ans assign the remaining indices
        else:
            # If the remaining inversion count is
            # greater than 0
            if (k == 0):
                i -= 1
 
            else:
                p[i] = k + 1
 
            # Set the next index as 1
            p[i + 1] = 1
 
            # Loop to assign the remaining indices
            for j in range(i+2, n+1):
                p[j] = p[j - 1] + 1
 
                # If current element already occured
                if (p[i] == p[j]):
                    p[j] += 1
 
            break
 
    # Print Answer
    for j in range(1, n+1):
        print(p[j], end=" ")
 
 
# Driver code
if __name__ == "__main__":
 
    n = 5
    k = 4
 
    findPermutation(n, k)
 
# This code is contributed by rakeshsahni


Javascript


C#
// C# program for the above approach
using System;
 
public class GFG {
   
// Function to fint the permutation of
// N natural numbers with k inversions
static void findPermutation(int n, int k)
{
   
    // Stores the maximum number of inversions
    int max_inv = (n * (n - 1)) / 2;
 
    // If required inversions are more that max
    if (k > max_inv) {
         Console.WriteLine("-1");
        return;
    }
 
    // Stores the final permutation
    int [] p = new int[n+1];
 
    // Keep track of the current max element
    // in the permutation
    int curr = n;
    int i = 1;
 
    // Loop to iterate through the array
    for (i = 1; i <= n; i++) {
 
        // Set current element as ith element
        // in order to increase n-i inversions
        // in the given permutation
        if (k >= n - i) {
            p[i] = curr;
            curr--;
            k -= (n - i);
        }
 
        // Otherwise set (k+1) element at ith index
        // ans assign the remaining indices
        else {
            // If the remaining inversion count is
            // greater than 0
            if (k == 0) {
                i--;
            }
            else {
                p[i] = k + 1;
            }
 
            // Set the next index as 1
            p[i + 1] = 1;
 
            // Loop to assign the remaining indices
            for (int j = i + 2; j <= n; j++) {
                p[j] = p[j - 1] + 1;
 
                // If current element already occured
                if (p[i] == p[j]) {
                    p[j]++;
                }
            }
            break;
        }
    }
 
    // Print Answer
    for (int j = 1; j <= n; j++) {
         Console.Write(p[j] + " ");
    }
}
 
// Driver code
    public static void Main (string[] args) {
       int n = 5;
       int k = 4;
 
    findPermutation(n, k);
    }
}
 
// This code is contributed by AnkThon


输出
5 1 2 3 4 

时间复杂度: O(N)
辅助空间: O(N)