Given a string of length m containing lowercase alphabets only. We need to find the n-th permutation of string lexicographic ally.
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 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.
Implementation:
C++
// 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 factorials void precomputeFactorials()
{ fact[0] = 1;
for ( int i = 1; i < MAX_FACT; i++)
fact[i] = fact[i - 1] * i;
} // Function for nth permutation void 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 program int main()
{ int n = 2;
char str[] = "geeksquiz" ;
nPermute(str, n);
return 0;
} |
Java
// Java program to print // n-th permutation public 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
# Python3 program to print n-th permutation MAX_CHAR = 26
MAX_FACT = 20
fact = [ None ] * (MAX_FACT)
# Utility for calculating factorials def precomputeFactorials():
fact[ 0 ] = 1
for i in range ( 1 , MAX_FACT):
fact[i] = fact[i - 1 ] * i
# Function for nth permutation def 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 Code if __name__ = = "__main__" :
n = 2
string = "geeksquiz"
nPermute(string, n)
# This code is contributed by Rituraj Jain |
C#
// C# program to print n-th permutation using 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. |
Javascript
<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 factorial
function precomputeFactorirals()
{ fact[0] = 1;
for (let i = 1; i < MAX_FACT; i++)
fact[i] = fact[i - 1] * i;
} // Function for nth permutation function 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 stub let n = 2; let str = "geeksquiz" ;
nPermute(str, n); // This code is contributed by avanitrachhadiya2155 </script> |
Output
eegikqszu
Complexity Analysis:
- Time Complexity: O(N^2), where N is the length of the input string.
- Auxiliary Space: O(MAX_CHAR), which is the size of the freq and out arrays