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++ program to demonstrate working of // prev_permutation() #include <bits/stdc++.h> using namespace std;
// Driver code 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;
} |
# Python implementation of above approach # Python program to demonstrate working of # prev_permutation() # import required module import itertools
# Driver code if __name__ = = "__main__" :
str = "4321"
# using permutations function to get all
# possible permutations
permut = itertools.permutations( str )
# Using for loop to iterate through permutations
# to find the previous permutation of str
for val in permut:
if "".join(val) = = str :
print ( "Previous permutation is " , end = "")
# Print the previous permutation
print ("".join( next (permut)))
break
else :
print ( "Previous permutation doesn't exist" )
# This code is contributed by codebraxnzt |
// Java program for the above approach import java.util.Arrays;
public class Main {
// Driver Code
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) {
// Find the non-increasing suffix
int n = arr.length;
int i = n - 2 ;
while (i >= 0 && arr[i] <= arr[i + 1 ]) {
i--;
}
// If the entire array is non-increasing, it's the last permutation
if (i < 0 ) {
return false ;
}
// Find the rightmost element that's smaller than the pivot
int j = n - 1 ;
while (j > i && arr[j] >= arr[i]) {
j--;
}
// Swap the pivot with the rightmost element that's smaller than the pivot
swap(arr, i, j);
// Reverse the suffix
reverse(arr, i + 1 , n - 1 );
return true ;
}
// function for swapping
static void swap( char [] arr, int i, int j) {
char temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
// function for reversing
static void reverse( char [] arr, int i, int j) {
while (i < j) {
swap(arr, i, j);
i++;
j--;
}
}
} // This code is contributed by Prince Kumar |
// JavaScript program to demonstrate working of prev_permutation() function prev_permutation(str) {
// Convert the string to an array
let arr = str.split( "" );
// Find the non-increasing suffix
let i = arr.length - 1;
while (i > 0 && arr[i - 1] <= arr[i]) {
i--;
}
// If the entire array is non-increasing, it's the last permutation
if (i <= 0) {
return false ;
}
// Find the rightmost element that's smaller than the pivot
let j = arr.length - 1;
while (arr[j] >= arr[i - 1]) {
j--;
}
// Swap the pivot with the rightmost element that's smaller than the pivot
let temp = arr[i - 1];
arr[i - 1] = arr[j];
arr[j] = temp;
// Reverse the suffix
j = arr.length - 1;
while (i < j) {
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
i++;
j--;
}
// Convert the array back to a string and return
return arr.join( "" );
} // Driver code let str = "4321" ;
let result = prev_permutation(str); if (result) {
console.log( "Previous permutation is " + result);
} else {
console.log( "Previous permutation doesn't exist" );
} // This code is contributed by adityashatmfh |
using System;
class Program {
static string prev_permutation( string str)
{
// Convert the string to an array
char [] arr = str.ToCharArray();
// Find the non-increasing suffix
int i = arr.Length - 1;
while (i > 0 && arr[i - 1] <= arr[i]) {
i--;
}
// If the entire array is non-increasing, it's the
// last permutation
if (i <= 0) {
return "Previous permutation doesn't exist" ;
}
// Find the rightmost element that's smaller than
// the pivot
int j = arr.Length - 1;
while (arr[j] >= arr[i - 1]) {
j--;
}
// Swap the pivot with the rightmost element that's
// smaller than the pivot
char temp = arr[i - 1];
arr[i - 1] = arr[j];
arr[j] = temp;
// Reverse the suffix
j = arr.Length - 1;
while (i < j) {
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
i++;
j--;
}
// Convert the array back to a string and return
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);
}
}
} |
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++ program to print all permutations with // duplicates allowed using prev_permutation() #include <bits/stdc++.h> using namespace std;
// Function to compute the previous permutation bool prevPermutation(string& str)
{ // Find index of the last element of the string
int n = str.length() - 1;
// Find largest index i such that str[i - 1] >
// str[i]
int i = n;
while (i > 0 && str[i - 1] <= str[i])
i--;
// if string is sorted in ascending order
// we're at the last permutation
if (i <= 0)
return false ;
// Note - str[i..n] is sorted in ascending order
// Find rightmost element's index that is less
// than str[i - 1]
int j = i - 1;
while (j + 1 <= n && str[j + 1] < str[i - 1])
j++;
// Swap character at i-1 with j
swap(str[i - 1], str[j]);
// Reverse the substring [i..n]
reverse(str.begin() + i, str.end());
return true ;
} // Driver code int main()
{ string str = "4321" ;
if (prevPermutation(str))
cout << "Previous permutation is " << str;
else
cout << "Previous permutation doesn't exist" ;
return 0;
} |
// Java program to print all // permutations with duplicates // allowed using prev_permutation() class GFG {
// Function to compute
// the previous permutation
static boolean prevPermutation( char [] str)
{
// Find index of the last
// element of the string
int n = str.length - 1 ;
// Find largest index i such
// that str[i - 1] > str[i]
int i = n;
while (i > 0 && str[i - 1 ] <= str[i]) {
i--;
}
// if string is sorted in
// ascending order we're
// at the last permutation
if (i <= 0 ) {
return false ;
}
// Note - str[i..n] is sorted
// in ascending order Find
// rightmost element's index
// that is less than str[i - 1]
int j = i - 1 ;
while (j + 1 <= n && str[j + 1 ] <= str[i - 1 ]) {
j++;
}
// Swap character at i-1 with j
swap(str, i - 1 , j);
// Reverse the substring [i..n]
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);
}
// Driver code
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" );
}
}
} // This code is contributed by 29AjayKumar |
# Python 3 program to # print all permutations with # duplicates allowed # using prev_permutation() # Function to compute the # previous permutation def prevPermutation( str ):
# Find index of the last element
# of the string
n = len ( str ) - 1
# Find largest index i such that
# str[i - 1] > str[i]
i = n
while (i > 0 and str [i - 1 ] < = str [i]):
i - = 1
# if string is sorted in ascending order
# we're at the last permutation
if (i < = 0 ):
return False , str
# Note - str[i..n] is sorted in
# ascending order
# Find rightmost element's index
# that is less than str[i - 1]
j = i - 1
while (j + 1 < = n and
str [j + 1 ] < str [i - 1 ]):
j + = 1
# Swap character at i-1 with j
str = list ( str )
temp = str [i - 1 ]
str [i - 1 ] = str [j]
str [j] = temp
str = ''.join( str )
# Reverse the substring [i..n]
str [i:: - 1 ]
return True , str
# Driver code if __name__ = = '__main__' :
str = "133"
b, str = prevPermutation( str )
if (b = = True ):
print ( "Previous permutation is" , str )
else :
print ( "Previous permutation doesn't exist" )
# This code is contributed by # Sanjit_Prasad |
// C# program to print all // permutations with duplicates // allowed using prev_permutation() using System;
class GFG {
// Function to compute
// the previous permutation
static Boolean prevPermutation( char [] str)
{
// Find index of the last
// element of the string
int n = str.Length - 1;
// Find largest index i such
// that str[i - 1] > str[i]
int i = n;
while (i > 0 && str[i - 1] <= str[i]) {
i--;
}
// if string is sorted in
// ascending order we're
// at the last permutation
if (i <= 0) {
return false ;
}
// Note - str[i..n] is sorted
// in ascending order Find
// rightmost element's index
// that is less than str[i - 1]
int j = i - 1;
while (j + 1 <= n && str[j + 1] <= str[i - 1]) {
j++;
}
// Swap character at i-1 with j
swap(str, i - 1, j);
// Reverse the substring [i..n]
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--) {
// Swap values of left and right
char temp = temparray[left];
temparray[left] = temparray[right];
temparray[right] = temp;
}
return String.Join( "" , temparray);
}
// Driver code
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" );
}
}
} // This code is contributed by Rajput-Ji |
// Javascript program to print all // permutations with duplicates // allowed using prev_permutation() // Function to compute // the previous permutation function prevPermutation(str){
// Find index of the last
// element of the string
let n = str.length - 1;
// Find largest index i such
// that str[i - 1] > str[i]
let i = n;
while (i > 0 && str[i - 1] <= str[i]){
i--;
}
// If string is sorted in
// ascending order we're
// at the last permutation
if (i <= 0){
return false ;
}
// Note - str[i..n] is sorted
// in ascending order Find
// rightmost element's index
// that is less than str[i - 1]
let j = i - 1;
while (j + 1 <= n && str[j + 1] < str[i - 1]){
j++;
}
// Swap character at i-1 with j
const temper = str[i - 1];
str[i - 1] = str[j];
str[j] = temper;
// Reverse the substring [i..n]
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 ;
} // Driver code let str = "4321" .split( "" );
if (prevPermutation(str))
{ console.log( "Previous permutation is " +
(str).join( "" ));
} else { console.log( "Previous permutation" +
"doesn't exist" );
} // This code is contributed by Gautam goel (gautamgoel962) |
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.