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++
// 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 n 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 numbers string 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 code int main() { int n = 3, k = 4; string kth_perm_seq = findKthPermutation(n, k); cout << kth_perm_seq << endl; return 0; } |
Java
// Java program to Find // the kth Permutation // Sequence of first // n natural numbers import java.util.*; class GFG{ // Function to find the index of // number at first position of // kth sequence of set of size n static 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 numbers static 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 code public 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
# 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 n def 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 numbers def 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 code if __name__ = = '__main__' : n = 3 k = 4 kth_perm_seq = findKthPermutation(n, k) print (kth_perm_seq) # This code is contributed by rutvik_56 |
C#
// C# program to Find // the kth Permutation // Sequence of first // n natural numbers using System; using System.Collections.Generic; class GFG{ // Function to find the index of // number at first position of // kth sequence of set of size n static 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 numbers static 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 code public 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
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.