Given a string, find all lexicographically previous permutations of it.

The lexicographic or lexicographical order (also known as lexical order, dictionary order, alphabetical order) means that the words are arranged similarly as they are presumed to appear in a dictionary. For example, the lexicographically previous permutation of string DCBA is DCAB, for string DCAB is DBCA, and for string DBCA is DBAC.

 
A simple solution would be to use std::prev_permutation that generates the next smaller lexicographic permutation of a string. If the function can determine the previous permutation, it rearranges the characters as such and returns true. If this is not possible (because it is already at the lowest possible permutation), it rearranges the characters according to the last permutation (sorted in descending order) and returns false.

The implementation can be seen below in C++:

C++


Download  Run Code

Output:

BADC BACD ADCB ADBC ACDB ACBD ABDC ABCD

We can also implement our own prev_permutation function. The following algorithm generates the previous permutation lexicographically after a given permutation. It changes the permutation in-place.

  • Find the largest index i such that str[i] is less than str[i-1].
  • Return false if i is the first index of the string, meaning that we are already at the lowest possible permutation, i.e., the string is sorted in ascending order. If i is not the first index of the string, the substring str[i…n) is sorted in ascending order, i.e. str[i-1] > str[i] <= str[i+1] <= str[i+2] <= … <= str[n-1].
  • Find the lowest index j to the right of index i such that str[j] is greater than str[i-1] and swap the character at index i-1 with index j-1.
  • Reverse substring str[i…n) and return true.

The algorithm can be implemented as follows in C++, Java, and Python:

C++


Download  Run Code

Output:

BADC BACD ADCB ADBC ACDB ACBD ABDC ABCD

Java


Download  Run Code

Output:

BADC
BACD
ADCB
ADBC
ACDB
ACBD
ABDC
ABCD

Python


Download  Run Code

Output:

BADC
BACD
ADCB
ADBC
ACDB
ACBD
ABDC
ABCD

The worst-case time complexity of the above solutions is O(n.n!) as there are n! permutations for a string of length n, and each permutation takes O(n) time. The worst case happens when the string contains all distinct elements.

 
Note that the above solution handles the strings containing repeated characters and does not print duplicate permutations.

 
Related Post:

Find all lexicographically next permutations of a string