Find n-th lexicographically permutation of a string | Set 2 - GeeksforGeeks

03 Sep, 2021
Given a string of length m containing lowercase alphabets only. We need to find the n-th permutation of string lexicographically.Examples:  
Input: str[] = "abc", n = 3
Output: Result = "bac"
All possible permutation in 
sorted order: abc, acb, bac,
bca, cab, cba

Input: str[] = "aba", n = 2
Output: Result = "aba"
All possible permutation 
in sorted order: aab, aba, baa
 
Naive Approach: Find lexicographically n-th permutation using STL.Efficient Approach: Mathematical concept for solving this problem.  
The total number of permutation of a string formed by N characters(all distinct) is N!The Total number of permutation of a string formed by N characters (where the frequency of character C1 is M1, C2 is M2... and so the frequency of character Ck is Mk) is N!/(M1! * M2! *....Mk!).The total number of permutation of a string formed by N characters(all distinct) after fixing the first character is (N-1)!
The total number of permutation of a string formed by N characters(all distinct) is N!
The Total number of permutation of a string formed by N characters (where the frequency of character C1 is M1, C2 is M2... and so the frequency of character Ck is Mk) is N!/(M1! * M2! *....Mk!).
The total number of permutation of a string formed by N characters(all distinct) after fixing the first character is (N-1)!
The following steps can be followed to reach the solution.  
Count the frequencies of all characters in an array.
Now from the first smallest character present in the string(smallest index i such that freq[i] > 0), compute the number of maximum permutation possible after setting that particular i-th character as the first character.
If this sum value is more than given n, then set that character as the first result output character, and decrement freq[i]. Continue the same for the remaining n-1 characters.
On the other hand, if the count is less than the required n, then iterate for the next character in the frequency table and update the count over and over again until we find a character that produces a count greater than the required n.
 
C++
Java
Python3
C#
Javascript
// C++ program to print// n-th permutation#include <bits/stdc++.h>using namespace std; #define ll long long int const int MAX_CHAR = 26;const int MAX_FACT = 20;ll fact[MAX_FACT]; // Utility for calculating factorialsvoid precomputeFactorials(){    fact[0] = 1;    for (int i = 1; i < MAX_FACT; i++)        fact[i] = fact[i - 1] * i;} // Function for nth permutationvoid nPermute(char str[], int n){    precomputeFactorials();     // Length of given string    int len = strlen(str);     // Count frequencies of all    // characters    int freq[MAX_CHAR] = { 0 };    for (int i = 0; i < len; i++)        freq[str[i] - 'a']++;     // Out string for output string    char out[MAX_CHAR];     // Iterate till sum equals n    int sum = 0;    int k = 0;     // We update both n and sum in this    // loop.    while (sum != n) {         sum = 0;        // Check for characters present in freq[]        for (int i = 0; i < MAX_CHAR; i++) {            if (freq[i] == 0)                continue;             // Remove character            freq[i]--;             // Calculate sum after fixing            // a particular char            int xsum = fact[len - 1 - k];            for (int j = 0; j < MAX_CHAR; j++)                xsum /= fact[freq[j]];            sum += xsum;             // if sum > n fix that char as            // present char and update sum            // and required nth after fixing            // char at that position            if (sum >= n) {                out[k++] = i + 'a';                n -= (sum - xsum);                break;            }             // if sum < n, add character back            if (sum < n)                freq[i]++;        }    }     // if sum == n means this    // char will provide its    // greatest permutation    // as nth permutation    for (int i = MAX_CHAR - 1;         k < len && i >= 0; i--)        if (freq[i]) {            out[k++] = i + 'a';            freq[i++]--;        }     // append string termination    // character and print result    out[k] = '\0';    cout << out;} // Driver programint main(){    int n = 2;    char str[] = "geeksquiz";     nPermute(str, n);    return 0;}
// Java program to print// n-th permutationpublic class PermuteString {    final static int MAX_CHAR = 26;    final static int MAX_FACT = 20;    static long fact[] = new long[MAX_FACT];     // Utility for calculating factorial    static void precomputeFactorirals()    {        fact[0] = 1;        for (int i = 1; i < MAX_FACT; i++)            fact[i] = fact[i - 1] * i;    }     // Function for nth permutation    static void nPermute(String str, int n)    {        precomputeFactorirals();         // length of given string        int len = str.length();         // Count frequencies of all        // characters        int freq[] = new int[MAX_CHAR];        for (int i = 0; i < len; i++)            freq[str.charAt(i) - 'a']++;         // out string for output string        String out = "";         // Iterate till sum equals n        int sum = 10;        int k = 0;         // We update both n and sum        // in this loop.        while (sum >= n) {             // Check for characters            // present in freq[]            for (int i = 0; i < MAX_CHAR; i++) {                if (freq[i] == 0)                    continue;                 // Remove character                freq[i]--;                 // calculate sum after fixing                // a particular char                sum = 0;                int xsum = (int)fact[len - 1 - k];                for (int j = 0; j < MAX_CHAR; j++)                    xsum /= fact[freq[j]];                sum += xsum;                 // if sum > n fix that char as                // present char and update sum                // and required nth after fixing                // char at that position                if (sum >= n) {                    out += (char)(i + 'a');                    k++;                    n -= (sum - xsum);                    break;                }                 // if sum < n, add character back                if (sum < n)                    freq[i]++;            }        }         // if sum == n means this        // char will provide its        // greatest permutation        // as nth permutation        for (int i = MAX_CHAR - 1;             k < len && i >= 0; i--)            if (freq[i] != 0) {                out += (char)(i + 'a');                freq[i++]--;            }         // append string termination        // character and print result        System.out.println(out);    }     // Driver program to test above method    public static void main(String[] args)    {         // TODO Auto-generated method stub        int n = 2;        String str = "geeksquiz";         nPermute(str, n);    }}// This code is contributed by Sumit Ghosh
# Python3 program to print n-th permutation MAX_CHAR = 26MAX_FACT = 20fact = [None] * (MAX_FACT) # Utility for calculating factorialsdef precomputeFactorials():     fact[0] = 1    for i in range(1, MAX_FACT):        fact[i] = fact[i - 1] * i # Function for nth permutationdef nPermute(string, n):     precomputeFactorials()     # length of given string    length = len(string)     # Count frequencies of all    # characters    freq = [0] * (MAX_CHAR)    for i in range(0, length):        freq[ord(string[i]) - ord('a')] += 1     # out string for output string    out = [None] * (MAX_CHAR)     # iterate till sum equals n    Sum, k = 0, 0     # We update both n and sum in    # this loop.    while Sum != n:         Sum = 0                 # check for characters present in freq[]        for i in range(0, MAX_CHAR):            if freq[i] == 0:                continue             # Remove character            freq[i] -= 1             # calculate sum after fixing            # a particular char            xsum = fact[length - 1 - k]            for j in range(0, MAX_CHAR):                xsum = xsum // fact[freq[j]]            Sum += xsum             # if sum > n fix that char as            # present char and update sum            # and required nth after fixing            # char at that position            if Sum >= n:                out[k] = chr(i + ord('a'))                n -= Sum - xsum                k += 1                break                         # if sum < n, add character back            if Sum < n:                freq[i] += 1             # if sum == n means this char will provide    # its greatest permutation as nth permutation    i = MAX_CHAR-1    while k < length and i >= 0:        if freq[i]:            out[k] = chr(i + ord('a'))            freq[i] -= 1            i += 1            k += 1                 i -= 1     # print result    print(''.join(out[:k])) # Driver Codeif __name__ == "__main__":     n = 2    string = "geeksquiz"     nPermute(string, n)     # This code is contributed by Rituraj Jain
// C# program to print n-th permutationusing System; public class GFG {     static int MAX_CHAR = 26;    static int MAX_FACT = 20;    static long[] fact = new long[MAX_FACT];     // utility for calculating factorial    static void precomputeFactorirals()    {        fact[0] = 1;        for (int i = 1; i < MAX_FACT; i++)            fact[i] = fact[i - 1] * i;    }     // function for nth permutation    static void nPermute(String str, int n)    {        precomputeFactorirals();         // length of given string        int len = str.Length;         // Count frequencies of all        // characters        int[] freq = new int[MAX_CHAR];         for (int i = 0; i < len; i++)            freq[str[i] - 'a']++;         // out string for output string        string ou = "";         // iterate till sum equals n        int sum = 10;        int k = 0;         // We update both n and sum in this        // loop.        while (sum >= n) {             // check for characters present in freq[]            for (int i = 0; i < MAX_CHAR; i++) {                if (freq[i] == 0)                    continue;                 // Remove character                freq[i]--;                 // calculate sum after fixing                // a particular char                sum = 0;                int xsum = (int)fact[len - 1 - k];                 for (int j = 0; j < MAX_CHAR; j++)                    xsum /= (int)(fact[freq[j]]);                 sum += xsum;                 // if sum > n fix that char as                // present char and update sum                // and required nth after fixing                // char at that position                if (sum >= n) {                    ou += (char)(i + 'a');                    k++;                    n -= (sum - xsum);                    break;                }                 // if sum < n, add character back                if (sum < n)                    freq[i]++;            }        }         // if sum == n means this char will provide its        // greatest permutation as nth permutation        for (int i = MAX_CHAR - 1; k < len && i >= 0; i--)            if (freq[i] != 0) {                ou += (char)(i + 'a');                freq[i++]--;            }         // append string termination        // character and print result        Console.Write(ou);    }     // Driver program to test above method    public static void Main()    {         // TODO Auto-generated method stub        int n = 2;        String str = "geeksquiz";         nPermute(str, n);    }} // This code is contributed by nitin mittal.
<script>// Javascript program to print// n-th permutation let MAX_CHAR = 26;let MAX_FACT = 20; let fact=new Array(MAX_FACT);  // Utility for calculating factorialfunction precomputeFactorirals(){    fact[0] = 1;        for (let i = 1; i < MAX_FACT; i++)            fact[i] = fact[i - 1] * i;} // Function for nth permutationfunction nPermute(str,n){    precomputeFactorirals();           // length of given string        let len = str.length;           // Count frequencies of all        // characters        let freq = new Array(MAX_CHAR);        for(let i=0;i<MAX_CHAR;i++)        {            freq[i]=0;        }        for (let i = 0; i < len; i++)            freq[str[i].charCodeAt(0) - 'a'.charCodeAt(0)]++;           // out string for output string        let out = "";           // Iterate till sum equals n        let sum = 10;        let k = 0;           // We update both n and sum        // in this loop.        while (sum >= n) {               // Check for characters            // present in freq[]            for (let i = 0; i < MAX_CHAR; i++) {                if (freq[i] == 0)                    continue;                   // Remove character                freq[i]--;                   // calculate sum after fixing                // a particular char                sum = 0;                let xsum = fact[len - 1 - k];                for (let j = 0; j < MAX_CHAR; j++)                    xsum = Math.floor(xsum/fact[freq[j]]);                sum += xsum;                   // if sum > n fix that char as                // present char and update sum                // and required nth after fixing                // char at that position                if (sum >= n) {                    out += String.fromCharCode(i + 'a'.charCodeAt(0));                    k++;                    n -= (sum - xsum);                    break;                }                   // if sum < n, add character back                if (sum < n)                    freq[i]++;            }        }           // if sum == n means this        // char will provide its        // greatest permutation        // as nth permutation        for (let i = MAX_CHAR - 1;             k < len && i >= 0; i--)            if (freq[i] != 0) {                out += String.fromCharCode(i + 'a'.charCodeAt(0));                freq[i++]--;            }           // append string termination        // character and print result        document.write(out);} // Driver program to test above method// TODO Auto-generated method stublet n = 2;let str = "geeksquiz"; nPermute(str, n); // This code is contributed by avanitrachhadiya2155</script>
Output:  
eegikqszu
Complexity Analysis:  
Time Complexity: O(n), where n is the nth permutation.
Space Complexity: O(n) where n is the space required to store the frequency.
This article is contributed by Shivam Pradhan (anuj_charm). If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above. 
nitin mittal
pvsdileep
rituraj_jain
andrew1234
avanitrachhadiya2155
sumitgumber28
simmytarika5
Accolite
Amazon
Cisco
MAQ Software
Samsung
Combinatorial
Recursion
Strings
Accolite
Amazon
Samsung
MAQ Software
Cisco
Strings
Recursion
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
Lexicographic rank of a string
Print all permutations in sorted (lexicographic) order
Print all subsets of given size of a set
Make all combinations of size k
Given an array A[] and a number x, check for pair in A[] with sum as x (aka Two Sum)
Recursion
Program for Tower of Hanoi
Program for Sum of the digits of a given number
Backtracking | Introduction