How to find Lexicographically previous permutation?

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




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


Python3




# 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




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




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


C#




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


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:

  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 as follows:  

C++




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




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




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




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




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


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.