Given a word, find a lexicographically smaller permutation of it. For example, lexicographically smaller permutation of “4321” is “4312” and the next smaller permutation of “4312” is “4231”. If the string is sorted in ascending order, the next lexicographically smaller permutation doesn’t exist.
We have discussed next_permutation() which modifies a string so that it stores lexicographically smaller permutations. STL also provides std::prev_permutation. It returns ‘true’ if the function could rearrange the object as a lexicographically smaller permutation. Otherwise, it returns ‘false’.
C++
#include <bits/stdc++.h>
using namespace std;
int main()
{
string str = "4321" ;
if (prev_permutation(str.begin(), str.end()))
cout << "Previous permutation is " << str;
else
cout << "Previous permutation doesn't exist" ;
return 0;
}
|
Python3
import itertools
if __name__ = = "__main__" :
str = "4321"
permut = itertools.permutations( str )
for val in permut:
if "".join(val) = = str :
print ( "Previous permutation is " , end = "")
print ("".join( next (permut)))
break
else :
print ( "Previous permutation doesn't exist" )
|
Java
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
char [] str = { '4' , '3' , '2' , '1' };
if (prev_permutation(str)) {
System.out.print( "Previous permutation is " );
System.out.println( new String(str));
} else {
System.out.print( "Previous permutation doesn't exist" );
}
}
static boolean prev_permutation( char [] arr) {
int n = arr.length;
int i = n - 2 ;
while (i >= 0 && arr[i] <= arr[i + 1 ]) {
i--;
}
if (i < 0 ) {
return false ;
}
int j = n - 1 ;
while (j > i && arr[j] >= arr[i]) {
j--;
}
swap(arr, i, j);
reverse(arr, i + 1 , n - 1 );
return true ;
}
static void swap( char [] arr, int i, int j) {
char temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
static void reverse( char [] arr, int i, int j) {
while (i < j) {
swap(arr, i, j);
i++;
j--;
}
}
}
|
Javascript
function prev_permutation(str) {
let arr = str.split( "" );
let i = arr.length - 1;
while (i > 0 && arr[i - 1] <= arr[i]) {
i--;
}
if (i <= 0) {
return false ;
}
let j = arr.length - 1;
while (arr[j] >= arr[i - 1]) {
j--;
}
let temp = arr[i - 1];
arr[i - 1] = arr[j];
arr[j] = temp;
j = arr.length - 1;
while (i < j) {
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
i++;
j--;
}
return arr.join( "" );
}
let str = "4321" ;
let result = prev_permutation(str);
if (result) {
console.log( "Previous permutation is " + result);
} else {
console.log( "Previous permutation doesn't exist" );
}
|
C#
using System;
class Program {
static string prev_permutation( string str)
{
char [] arr = str.ToCharArray();
int i = arr.Length - 1;
while (i > 0 && arr[i - 1] <= arr[i]) {
i--;
}
if (i <= 0) {
return "Previous permutation doesn't exist" ;
}
int j = arr.Length - 1;
while (arr[j] >= arr[i - 1]) {
j--;
}
char temp = arr[i - 1];
arr[i - 1] = arr[j];
arr[j] = temp;
j = arr.Length - 1;
while (i < j) {
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
i++;
j--;
}
return new string (arr);
}
static void Main( string [] args)
{
string str = "4321" ;
string result = prev_permutation(str);
if (result
!= "Previous permutation doesn't exist" ) {
Console.WriteLine( "Previous permutation is "
+ result);
}
else {
Console.WriteLine(result);
}
}
}
|
Output
Previous permutation is 4312
Time Complexity: O(N)m where N is the size of the given string.
Auxiliary Space: O(1), as constant space is used.
How to write our own prev_permutation()?
Below are steps to find the previous permutation:
- Find largest index i such that str[i – 1] > str[i].
- Find largest index j such that j >= i and str[j] < str[i – 1].
- Swap str[j] and str[i – 1].
- Reverse the sub-array starting at str[i].
Below is the implementation of above steps as follows:
C++
#include <bits/stdc++.h>
using namespace std;
bool prevPermutation(string& str)
{
int n = str.length() - 1;
int i = n;
while (i > 0 && str[i - 1] <= str[i])
i--;
if (i <= 0)
return false ;
int j = i - 1;
while (j + 1 <= n && str[j + 1] < str[i - 1])
j++;
swap(str[i - 1], str[j]);
reverse(str.begin() + i, str.end());
return true ;
}
int main()
{
string str = "4321" ;
if (prevPermutation(str))
cout << "Previous permutation is " << str;
else
cout << "Previous permutation doesn't exist" ;
return 0;
}
|
Java
class GFG {
static boolean prevPermutation( char [] str)
{
int n = str.length - 1 ;
int i = n;
while (i > 0 && str[i - 1 ] <= str[i]) {
i--;
}
if (i <= 0 ) {
return false ;
}
int j = i - 1 ;
while (j + 1 <= n && str[j + 1 ] <= str[i - 1 ]) {
j++;
}
swap(str, i - 1 , j);
StringBuilder sb
= new StringBuilder(String.valueOf(str));
sb.reverse();
str = sb.toString().toCharArray();
return true ;
}
static String swap( char [] ch, int i, int j)
{
char temp = ch[i];
ch[i] = ch[j];
ch[j] = temp;
return String.valueOf(ch);
}
public static void main(String[] args)
{
char [] str = "4321" .toCharArray();
if (prevPermutation(str)) {
System.out.println( "Previous permutation is "
+ String.valueOf(str));
}
else {
System.out.println( "Previous permutation"
+ "doesn't exist" );
}
}
}
|
Python
def prevPermutation( str ):
n = len ( str ) - 1
i = n
while (i > 0 and str [i - 1 ] < = str [i]):
i - = 1
if (i < = 0 ):
return False , str
j = i - 1
while (j + 1 < = n and
str [j + 1 ] < str [i - 1 ]):
j + = 1
str = list ( str )
temp = str [i - 1 ]
str [i - 1 ] = str [j]
str [j] = temp
str = ''.join( str )
str [i:: - 1 ]
return True , str
if __name__ = = '__main__' :
str = "133"
b, str = prevPermutation( str )
if (b = = True ):
print ( "Previous permutation is" , str )
else :
print ( "Previous permutation doesn't exist" )
|
C#
using System;
class GFG {
static Boolean prevPermutation( char [] str)
{
int n = str.Length - 1;
int i = n;
while (i > 0 && str[i - 1] <= str[i]) {
i--;
}
if (i <= 0) {
return false ;
}
int j = i - 1;
while (j + 1 <= n && str[j + 1] <= str[i - 1]) {
j++;
}
swap(str, i - 1, j);
String sb = String.Join( "" , str);
sb = reverse(sb);
str = sb.ToString().ToCharArray();
return true ;
}
static String swap( char [] ch, int i, int j)
{
char temp = ch[i];
ch[i] = ch[j];
ch[j] = temp;
return String.Join( "" , ch);
}
static String reverse(String input)
{
char [] temparray = input.ToCharArray();
int left, right = 0;
right = temparray.Length - 1;
for (left = 0; left < right; left++, right--) {
char temp = temparray[left];
temparray[left] = temparray[right];
temparray[right] = temp;
}
return String.Join( "" , temparray);
}
public static void Main(String[] args)
{
char [] str = "4321" .ToCharArray();
if (prevPermutation(str)) {
Console.WriteLine( "Previous permutation is "
+ String.Join( "" , str));
}
else {
Console.WriteLine( "Previous permutation"
+ "doesn't exist" );
}
}
}
|
Javascript
function prevPermutation(str){
let n = str.length - 1;
let i = n;
while (i > 0 && str[i - 1] <= str[i]){
i--;
}
if (i <= 0){
return false ;
}
let j = i - 1;
while (j + 1 <= n && str[j + 1] < str[i - 1]){
j++;
}
const temper = str[i - 1];
str[i - 1] = str[j];
str[j] = temper;
let size = n-i+1;
for (let idx = 0; idx < Math.floor(size / 2); idx++) {
let temp = str[idx + i];
str[idx + i] = str[n - idx];
str[n - idx] = temp;
}
return true ;
}
let str = "4321" .split( "" );
if (prevPermutation(str))
{
console.log( "Previous permutation is " +
(str).join( "" ));
}
else
{
console.log( "Previous permutation" +
"doesn't exist" );
}
|
Output
Previous permutation is 4312
Time Complexity: O(N)m where N is the size of the given string.
Auxiliary Space: O(1), as constant space is used.
This article is contributed by Aarti_Rathi and Aditya Goel. If you like GeeksforGeeks and would like to contribute, you can also write an article and 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 if you want to share more information about the topic discussed above.