Open In App

How to find Lexicographically previous permutation?

Improve
Improve
Like Article
Like
Save
Share
Report

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.



Last Updated : 27 Mar, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads