Find the K-th Permutation Sequence of first N natural numbers - GeeksforGeeks

19 Jan, 2021
Given two integers N and K, find the Kth permutation sequence of numbers from 1 to N without using STL function.Note: Assume that the inputs are such that Kth permutation of N number is always possible.
Examples: 
Input: N = 3, K = 4 Output: 231 Explanation: The ordered list of permutation sequence from integer 1 to 3 is : 123, 132, 213, 231, 312, 321. So, the 4th permutation sequence is “231”.
Input: N = 2, K = 1 Output: 12 Explanation: For n = 2, only 2 permutations are possible 12 21. So, the 1st permutation sequence is “12”.  
Naive Approach:To solve the problem mentioned above the simple approach is to find all permutation sequences and output the kth out of them. But this method is not so efficient and takes more time, hence it can be optimized.
Efficient Approach:To optimize the above method mentioned above, observe that the value of k can be directly used to find the number at each index of the sequence.  
The first position of an n length sequence is occupied by each of the numbers from 1 to n exactly n! / n that is (n-1)! number of times and in ascending order. So the first position of the kth sequence will be occupied by the number present at index = k / (n-1)! (according to 1-based indexing).
The currently found number can not occur again so it is removed from the original n numbers and now the problem reduces to finding the ( k % (n-1)! )th permutation sequence of the remaining n-1 numbers.
This process can be repeated until we have only one number left which will be placed in the first position of the last 1-length sequence.
The factorial values involved here can be very large as compared to k. So, the trick used to avoid the full computation of such large factorials is that as soon as the product n * (n-1) * ... becomes greater than k, we no longer need to find the actual factorial value because: 
k / n_actual_factorial_value = 0 and k / n_partial_factorial_value = 0 when partial_factorial_value > k  
Below is the implementation of the above approach: 
C++
Java
Python3
C#
// C++ program to Find the kth Permutation// Sequence of first n natural numbers #include <bits/stdc++.h>using namespace std; // Function to find the index of number// at first position of// kth sequence of set of size nint findFirstNumIndex(int& k, int n){     if (n == 1)        return 0;    n--;     int first_num_index;    // n_actual_fact = n!    int n_partial_fact = n;     while (k >= n_partial_fact           && n > 1) {        n_partial_fact            = n_partial_fact              * (n - 1);        n--;    }     // First position of the    // kth sequence will be    // occupied by the number present    // at index = k / (n-1)!    first_num_index = k / n_partial_fact;     k = k % n_partial_fact;     return first_num_index;} // Function to find the// kth permutation of n numbersstring findKthPermutation(int n, int k){    // Store final answer    string ans = "";     set<int> s;     // Insert all natural number    // upto n in set    for (int i = 1; i <= n; i++)        s.insert(i);     set<int>::iterator itr;     // Mark the first position    itr = s.begin();     // subtract 1 to get 0 based indexing    k = k - 1;     for (int i = 0; i < n; i++) {         int index            = findFirstNumIndex(k, n - i);         advance(itr, index);         // itr now points to the        // number at index in set s        ans += (to_string(*itr));         // remove current number from the set        s.erase(itr);         itr = s.begin();    }    return ans;} // Driver codeint main(){     int n = 3, k = 4;     string kth_perm_seq        = findKthPermutation(n, k);     cout << kth_perm_seq << endl;     return 0;}
// Java program to Find// the kth Permutation// Sequence of first// n natural numbersimport java.util.*;class GFG{ // Function to find the index of// number at first position of// kth sequence of set of size nstatic int findFirstNumIndex(int k,                             int n){  if (n == 1)    return 0;  n--;   int first_num_index;     // n_actual_fact = n!  int n_partial_fact = n;   while (k >= n_partial_fact && n > 1)  {    n_partial_fact = n_partial_fact *                     (n - 1);    n--;  }   // First position of the  // kth sequence will be  // occupied by the number present  // at index = k / (n-1)!  first_num_index = k / n_partial_fact;   k = k % n_partial_fact;  return first_num_index;} // Function to find the// kth permutation of n numbersstatic String findKthPermutation(int n,                                 int k){  // Store final answer  String ans = "";   HashSet<Integer> s = new HashSet<>();   // Insert all natural number  // upto n in set  for (int i = 1; i <= n; i++)    s.add(i);   Vector<Integer> v = new Vector<>();  v.addAll(s);   // Mark the first position  int itr = v.elementAt(0);     // Subtract 1 to  // get 0 based  // indexing  k = k - 1;   for (int i = 0; i < n; i++)  {    int index = findFirstNumIndex(k,                                  n - i);         // itr now points to the    // number at index in set s    if(index < v.size())    {      ans += ((v.elementAt(index).toString()));      v.remove(index);    }    else      ans += String.valueOf(itr + 2);     // Remove current number    // from the set    itr = v.elementAt(0);  }  return ans;} // Driver codepublic static void main(String[] args){  int n = 3, k = 4;  String kth_perm_seq = findKthPermutation(n, k);  System.out.print(kth_perm_seq + "\n");}} // This code is contributed by Rajput-Ji
# Python3 program to find the kth permutation# Sequence of first n natural numbers # Function to find the index of number# at first position of kth sequence of# set of size ndef findFirstNumIndex(k, n):     if (n == 1):        return 0, k             n -= 1     first_num_index = 0         # n_actual_fact = n!    n_partial_fact = n     while (k >= n_partial_fact and n > 1):        n_partial_fact = n_partial_fact * (n - 1)        n -= 1     # First position of the kth sequence    # will be occupied by the number present    # at index = k / (n-1)!    first_num_index = k // n_partial_fact     k = k % n_partial_fact     return first_num_index, k # Function to find the# kth permutation of n numbersdef findKthPermutation(n, k):     # Store final answer    ans = ""     s = set()     # Insert all natural number    # upto n in set    for i in range(1, n + 1):        s.add(i)     # Subtract 1 to get 0 based indexing    k = k - 1     for i in range(n):         # Mark the first position        itr = list(s)         index, k = findFirstNumIndex(k, n - i)         # itr now points to the        # number at index in set s        ans += str(itr[index])         # remove current number from the set        itr.pop(index)                 s = set(itr)         return ans # Driver codeif __name__=='__main__':     n = 3    k = 4         kth_perm_seq = findKthPermutation(n, k)     print(kth_perm_seq) # This code is contributed by rutvik_56
// C# program to Find// the kth Permutation// Sequence of first// n natural numbersusing System;using System.Collections.Generic;class GFG{ // Function to find the index of// number at first position of// kth sequence of set of size nstatic int findFirstNumIndex(int k,                             int n){  if (n == 1)    return 0;  n--;   int first_num_index;   // n_actual_fact = n!  int n_partial_fact = n;   while (k >= n_partial_fact && n > 1)  {    n_partial_fact = n_partial_fact *                     (n - 1);    n--;  }   // First position of the  // kth sequence will be  // occupied by the number present  // at index = k / (n-1)!  first_num_index = k / n_partial_fact;   k = k % n_partial_fact;  return first_num_index;} // Function to find the// kth permutation of n numbersstatic String findKthPermutation(int n,                                 int k){  // Store readonly answer  String ans = "";   HashSet<int> s = new HashSet<int>();   // Insert all natural number  // upto n in set  for (int i = 1; i <= n; i++)    s.Add(i);   List<int> v = new List<int>(s);   // Mark the first position  int itr = v[0];   // Subtract 1 to  // get 0 based  // indexing  k = k - 1;   for (int i = 0; i < n; i++)  {    int index = findFirstNumIndex(k, n - i);     // itr now points to the    // number at index in set s    if(index < v.Count)    {      ans += ((v[index].ToString()));      v.RemoveAt(index);    }    else      ans += String.Join("", itr + 2);     // Remove current number    // from the set    itr = v[0];  }  return ans;} // Driver codepublic static void Main(String[] args){  int n = 3, k = 4;  String kth_perm_seq = findKthPermutation(n, k);  Console.Write(kth_perm_seq + "\n");}} // This code is contributed by Rajput-Ji
231
 
Rajput-Ji
rutvik_56
Natural Numbers
permutation
Combinatorial
Mathematical
Mathematical
permutation
Combinatorial
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Python program to get all subsets of given size of a set
Heap's Algorithm for generating permutations
Distinct permutations of the string | Set 2
Make all combinations of size k
Count Derangements (Permutation such that no element appears in its original position)
Program for Fibonacci numbers
C++ Data Types
Set in C++ Standard Template Library (STL)
Coin Change | DP-7
Merge two sorted arrays