Given a string, print all permutations of it in sorted order. For example, if the input string is “ABC”, then output should be “ABC, ACB, BAC, BCA, CAB, CBA”.
We have discussed a program to print all permutations in this post, but here we must print the permutations in increasing order.
Algorithm to print the permutations lexicographic-ally:
Step 1. Sort the given string in non-decreasing order and print it. The first permutation is always the string sorted in non-decreasing order.
Step 2. Start generating next higher permutation. Do it until next higher permutation is not possible. If we reach a permutation where all characters are sorted and in non-increasing order, then that permutation is the last permutation.
Steps to generate the next higher permutation:
Step 1. Take the previously printed permutation and find the rightmost character in it, which is smaller than its next character. Let us call this character as ‘first character’.
Step 2. Now find the ceiling of the ‘first character’. Ceiling is the smallest character on right of ‘first character’, which is greater than ‘first character’. Let us call the ceil character as ‘second character’.
Step 3. Swap the two characters found in above 2 steps.
Step 4. Sort the substring (in non-decreasing order) after the original index of ‘first character’.
Approach:
1. Let us consider the string “ABCDEF”. Let the previously printed permutation be “DCFEBA”.
2. The next permutation in sorted order should be “DEABCF”.
3. Let us understand above steps to find next permutation. The ‘first character’ will be ‘C’. The ‘second character’ will be ‘E’. After swapping these two, we get “DEFCBA”.
4. The final step is to sort the substring after the character original index of ‘first character’. Finally, we get “DEABCF”.
Following is the implementation of the algorithm.
C++
#include <bits/stdc++.h>
using namespace std;
int compare ( const void *a, const void * b)
{ return ( *( char *)a - *( char *)b ); }
void swap ( char * a, char * b)
{
char t = *a;
*a = *b;
*b = t;
}
int findCeil ( char str[], char first, int l, int h)
{
int ceilIndex = l;
for ( int i = l+1; i <= h; i++)
if (str[i] > first && str[i] < str[ceilIndex])
ceilIndex = i;
return ceilIndex;
}
void sortedPermutations ( char str[] )
{
int size = strlen (str);
qsort ( str, size, sizeof ( str[0] ), compare );
bool isFinished = false ;
while ( ! isFinished )
{
cout << str << endl;
int i;
for ( i = size - 2; i >= 0; --i )
if (str[i] < str[i+1])
break ;
if ( i == -1 )
isFinished = true ;
else
{
int ceilIndex = findCeil( str, str[i], i + 1, size - 1 );
swap( &str[i], &str[ceilIndex] );
qsort ( str + i + 1, size - i - 1, sizeof (str[0]), compare );
}
}
}
int main()
{
char str[] = "ABCD" ;
sortedPermutations( str );
return 0;
}
|
C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int compare ( const void *a, const void * b)
{ return ( *( char *)a - *( char *)b ); }
void swap ( char * a, char * b)
{
char t = *a;
*a = *b;
*b = t;
}
int findCeil ( char str[], char first, int l, int h)
{
int ceilIndex = l;
for ( int i = l+1; i <= h; i++)
if (str[i] > first && str[i] < str[ceilIndex])
ceilIndex = i;
return ceilIndex;
}
void sortedPermutations ( char str[] )
{
int size = strlen (str);
qsort ( str, size, sizeof ( str[0] ), compare );
bool isFinished = false ;
while ( ! isFinished )
{
printf ( "%s \n" , str);
int i;
for ( i = size - 2; i >= 0; --i )
if (str[i] < str[i+1])
break ;
if ( i == -1 )
isFinished = true ;
else
{
int ceilIndex = findCeil( str, str[i], i + 1, size - 1 );
swap( &str[i], &str[ceilIndex] );
qsort ( str + i + 1, size - i - 1, sizeof (str[0]), compare );
}
}
}
int main()
{
char str[] = "ABCD" ;
sortedPermutations( str );
return 0;
}
|
Java
import java.util.*;
class GFG
{
static int findCeil( char [] str, char first, int l,
int h)
{
int ceilIndex = l;
for ( int i = l + 1 ; i <= h; i++)
if (str[i] > first && str[i] < str[ceilIndex])
ceilIndex = i;
return ceilIndex;
}
static void sortedPermutations( char [] str)
{
int size = str.length;
Arrays.sort(str);
boolean isFinished = false ;
while (!isFinished) {
System.out.println(String.valueOf(str));
int i;
for (i = size - 2 ; i >= 0 ; --i)
if (str[i] < str[i + 1 ])
break ;
if (i == - 1 )
isFinished = true ;
else {
int ceilIndex = findCeil(str, str[i], i + 1 ,
size - 1 );
char temp = str[i];
str[i] = str[ceilIndex];
str[ceilIndex] = temp;
Arrays.sort(str, i + 1 , size);
}
}
}
public static void main(String[] args)
{
char [] str = { 'A' , 'B' , 'C' , 'D' };
sortedPermutations(str);
}
}
|
Python3
def findCeil(str_, first, l, h):
ceilIndex = l
for i in range (l + 1 , h + 1 ):
if (str_[i] > first and str_[i] < str_[ceilIndex]):
ceilIndex = i
return ceilIndex
def sortedPermutations(str_):
size = len (str_)
str_ = sorted (str_)
isFinished = False
while (isFinished is False ):
print ("".join(str_))
i = size - 2
while i > = 0 :
if (str_[i] < str_[i + 1 ]):
break
i - = 1
if (i = = - 1 ):
isFinished = True
else :
ceilIndex = findCeil(str_, str_[i], i + 1 , size - 1 )
temp = str_[i]
str_[i] = str_[ceilIndex]
str_[ceilIndex] = temp
str_ = str_[:i + 1 ] + sorted (str_[i + 1 :])
str_ = "ABCD"
sortedPermutations(str_)
|
C#
using System;
using System.Collections.Generic;
class GFG {
static int findCeil( char [] str, char first, int l,
int h)
{
int ceilIndex = l;
for ( int i = l + 1; i <= h; i++)
if (str[i] > first && str[i] < str[ceilIndex])
ceilIndex = i;
return ceilIndex;
}
static void sortedPermutations( char [] str)
{
int size = str.Length;
Array.Sort(str);
bool isFinished = false ;
while (!isFinished) {
Console.WriteLine( new string (str));
int i;
for (i = size - 2; i >= 0; --i)
if (str[i] < str[i + 1])
break ;
if (i == -1)
isFinished = true ;
else {
int ceilIndex = findCeil(str, str[i], i + 1,
size - 1);
char temp = str[i];
str[i] = str[ceilIndex];
str[ceilIndex] = temp;
Array.Sort(str, i + 1, size - i - 1);
}
}
}
public static void Main( string [] args)
{
char [] str = { 'A' , 'B' , 'C' , 'D' };
sortedPermutations(str);
}
}
|
Javascript
function compare (a, b)
{
return a.charCodeAt(0) - b.charCodeAt(0);
}
function findCeil (str, first, l, h)
{
let ceilIndex = l;
for (let i = l+1; i <= h; i++)
if (str[i] > first && str[i] < str[ceilIndex])
ceilIndex = i;
return ceilIndex;
}
function sortedPermutations ( str)
{
let size = str.length;
str = str.split( "" );
str.sort(compare);
let isFinished = false ;
while ( ! isFinished )
{
console.log(str.join( "" ));
let i;
for ( i = size - 2; i >= 0; --i )
if (str[i] < str[i+1])
break ;
if ( i == -1 )
isFinished = true ;
else
{
let ceilIndex = findCeil( str, str[i], i + 1, size - 1 );
let temp = str[i];
str[i] = str[ceilIndex];
str[ceilIndex] = temp;
str1 = str.slice(i + 1);
str1.sort();
str = str.slice(0, i + 1);
str.push(...str1);
}
}
}
let str = "ABCD" ;
sortedPermutations( str );
|
Output:
ABCD
ABDC
....
....
DCAB
DCBA
Time Complexity: O(n2 x n!)
Auxiliary Space: O(n)
We can optimize step 4 of the above algorithm for finding next permutation. Instead of sorting the subarray after the ‘first character’, we can reverse the subarray, because the subarray we get after swapping is always sorted in non-increasing order. This optimization makes the time complexity as O(n x n!).
See following optimized code.
C++
#include <bits/stdc++.h>
using namespace std;
void reverse( char str[], int l, int h)
{
while (l < h)
{
swap(&str[l], &str[h]);
l++;
h--;
}
}
void sortedPermutations ( char str[] )
{
int size = strlen (str);
qsort ( str, size, sizeof ( str[0] ), compare );
bool isFinished = false ;
while ( ! isFinished )
{
cout << str << endl;
int i;
for ( i = size - 2; i >= 0; --i )
if (str[i] < str[i+1])
break ;
if ( i == -1 )
isFinished = true ;
else
{
int ceilIndex = findCeil( str, str[i], i + 1, size - 1 );
swap( &str[i], &str[ceilIndex] );
reverse( str, i + 1, size - 1 );
}
}
}
|
C
void reverse( char str[], int l, int h)
{
while (l < h)
{
swap(&str[l], &str[h]);
l++;
h--;
}
}
void sortedPermutations ( char str[] )
{
int size = strlen (str);
qsort ( str, size, sizeof ( str[0] ), compare );
bool isFinished = false ;
while ( ! isFinished )
{
printf ( "%s \n" , str);
int i;
for ( i = size - 2; i >= 0; --i )
if (str[i] < str[i+1])
break ;
if ( i == -1 )
isFinished = true ;
else
{
int ceilIndex = findCeil( str, str[i], i + 1, size - 1 );
swap( &str[i], &str[ceilIndex] );
reverse( str, i + 1, size - 1 );
}
}
}
|
Java
import java.util.*;
class GFG
{
static void swap( char [] str, int i, int j)
{
char t = str[i];
str[i] = str[j];
str[j] = t;
}
static void reverse( char str[], int l, int h)
{
while (l < h) {
swap(str, l, h);
l++;
h--;
}
}
static int findCeil( char str[], char first, int l,
int h)
{
int ceilIndex = l;
for ( int i = l + 1 ; i <= h; i++)
if (str[i] > first && str[i] < str[ceilIndex])
ceilIndex = i;
return ceilIndex;
}
static void sortedPermutations( char str[])
{
int size = str.length;
Arrays.sort(str);
boolean isFinished = false ;
while (!isFinished) {
System.out.println(str);
int i;
for (i = size - 2 ; i >= 0 ; --i)
if (str[i] < str[i + 1 ])
break ;
if (i == - 1 )
isFinished = true ;
else {
int ceilIndex = findCeil(str, str[i], i + 1 ,
size - 1 );
swap(str, i, ceilIndex);
reverse(str, i + 1 , size - 1 );
}
}
}
public static void main(String[] args)
{
char str[] = "ABCD" .toCharArray();
sortedPermutations(str);
}
}
|
Python3
def reverse( str , l, h):
while (l < h) :
str [l], str [h] = str [h], str [l]
l + = 1
h - = 1
return str
def findCeil( str , c, k, n):
ans = - 1
val = c
for i in range (k, n + 1 ):
if str [i] > c and str [i] < val:
val = str [i]
ans = i
return ans
def sortedPermutations( str ):
size = len ( str )
str = ''.join( sorted ( str ))
isFinished = False
while ( not isFinished):
print ( str )
for i in range (size - 2 , - 1 , - 1 ):
if ( str [i] < str [i + 1 ]):
break
if (i = = - 1 ):
isFinished = True
else :
ceilIndex = findCeil( str , str [i], i + 1 ,
size - 1 )
str [i], str [ceilIndex] = str [ceilIndex], str [i]
str = reverse( str , i + 1 , size - 1 )
|
C#
using System;
public class GFG {
static void swap( char [] str, int i, int j) {
char t = str[i];
str[i] = str[j];
str[j] = t;
}
static void reverse( char []str, int l, int h) {
while (l < h) {
swap(str, l, h);
l++;
h--;
}
}
static int findCeil( char []str, char first, int l, int h) {
int ceilIndex = l;
for ( int i = l + 1; i <= h; i++)
if (str[i] > first && str[i] < str[ceilIndex])
ceilIndex = i;
return ceilIndex;
}
static void sortedPermutations( char []str) {
int size = str.Length;
Array.Sort(str);
bool isFinished = false ;
while (!isFinished) {
Console.WriteLine(str);
int i;
for (i = size - 2; i >= 0; --i)
if (str[i] < str[i + 1])
break ;
if (i == -1)
isFinished = true ;
else {
int ceilIndex = findCeil(str, str[i], i + 1, size - 1);
swap(str, i, ceilIndex);
reverse(str, i + 1, size - 1);
}
}
}
public static void Main(String[] args) {
char []str = "ABCD" .ToCharArray();
sortedPermutations(str);
}
}
|
Javascript
<script>
function swap( str , i , j) {
var t = str[i];
str[i] = str[j];
str[j] = t;
}
function reverse( str , l , h) {
while (l < h) {
swap(str, l, h);
l++;
h--;
}
}
function findCeil( str, first , l , h) {
var ceilIndex = l;
for (i = l + 1; i <= h; i++)
if (str[i] > first && str[i] < str[ceilIndex])
ceilIndex = i;
return ceilIndex;
}
function sortedPermutations(str) {
var size = str.length;
str.sort();
var isFinished = false ;
while (!isFinished) {
var st = str.join( "" );
document.write(st+ "</br>" );
var i;
for (i = size - 2; i >= 0; --i)
if (str[i] < str[i + 1])
break ;
if (i == -1)
isFinished = true ;
else {
var ceilIndex = findCeil(str, str[i], i + 1, size - 1);
swap(str, i, ceilIndex);
reverse(str, i + 1, size - 1);
}
}
}
var str = "ABCD" ;
str = str.split( "" );
sortedPermutations(str);
</script>
|
Time Complexity: O(n*n!)
Auxiliary Space: O(n)
The above programs print duplicate permutation when characters are repeated. We can avoid it by keeping track of the previous permutation. While printing, if the current permutation is same as previous permutation, we won’t be printing it.
This article is compiled by Aashish Barnwal and reviewed by GeeksforGeeks team. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.