How to find Lexicographically previous permutation?

Given a word, find lexicographically smaller permutation of it. For example, lexicographically smaller permutation of “4321” is “4312” and 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() that modifies a string so that it stores lexicographically smaller permutation.
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’.

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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;
}

chevron_right


Output :

Previous permutation is 4312

How to write our own prev_permutation()?
Below are steps to find the previous permutation?
1. Find largest index i such that str[i – 1] > str[i].
2. Find largest index j such that j >= i and str[j] < str[i – 1].
3. Swap str[j] and str[i – 1].
4. Reverse the sub-array starting at str[i].

Below is the implementation of above steps.

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# 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
  
    # 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[::-1]
      
    return True, str
      
# Driver code
if __name__ == '__main__':
    str = "4321"
      
    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

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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

chevron_right


Output :

Previous permutation is 4312

This article is contributed by Aditya Goel. If you like GeeksforGeeks and would like to contribute, you can also write an article and mail your article to contribute@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



My Personal Notes arrow_drop_up