Lexicographically Next Permutation of given String
Last Updated :
06 Apr, 2023
All the permutations of a word when arranged in a dictionary, the order of words so obtained is called lexicographical order. in Simple words, it is the one that has all its elements sorted in ascending order, and the largest has all its elements sorted in descending order.
lexicographically is nothing but the greater permutation of it.
For reference: a b c d e f g h i j k l m n o p q r s t u v w x y z
For example, lexicographically next permutation of "gfg" is "ggf" and the next permutation of "acb" is "bac".
Note: In some cases, the next lexicographically greater word might not exist, e.g, “aaa” and “edcba”.
In C++, there is a specific function that saves us from a lot of code. It's in the file #include <algorithm>. The function is next_permutation(a.begin(), a.end()).
It returns 'true' if the function could rearrange the object as a lexicographically greater permutation. Otherwise, the function returns 'false'.
Example:
CPP
// C++ program to demonstrate next lexicographically
// greater permutation of a word
#include <algorithm>
#include <iostream>
using namespace std;
int main()
{
string s = { "gfg" };
bool val
= next_permutation(s.begin(),
s.end());
if (val == false)
cout << "No Word Possible"
<< endl;
else
cout << s << endl;
return 0;
}
Time Complexity: O(N), where N is the length of the given string.
Auxiliary Space: O(1), as constant extra space is used.
The same program can also be implemented without using STL. Below is the code snippet for the same.
The Idea is Based on the Following Facts:
- A sequence sorted in descending order does not have the next permutation. For example "edcba" does not have the next permutation.
- For a sequence that is not sorted in descending order for example "abedc", we can follow these steps.
- a) Traverse from the right and find the first item that is not following the ascending order. For example in "abedc", the character 'b' does not follow the ascending order.
- b) Swap the found character with the closest greater (or smallest greater) element on the right side of it. In the case of "abedc", we have 'c' as the closest greater element. After swapping 'b' and 'c', the string becomes "acedb".
- c) After swapping, reverse the string after the position of the character found in step a. After reversing the substring "edb" of "acedb", we get "acbde" which is the required next permutation.
Optimizations in steps b) and c)
a) Since the sequence is sorted in decreasing order, we can use binary search to find the closest greater element.
c) Since the sequence is already sorted in decreasing order (even after swapping as we swapped with the closest greater), we can get the sequence sorted (in increasing order) after reversing it.
CPP
// C++ program to demonstrate
// the next lexicographically
// greater permutation of a word
#include <iostream>
using namespace std;
void swap(char* a, char* b)
{
if (*a == *b)
return;
*a ^= *b;
*b ^= *a;
*a ^= *b;
}
void rev(string& s, int l, int r)
{
while (l < r)
swap(&s[l++], &s[r--]);
}
int bsearch(string& s, int l, int r, int key)
{
int index = -1;
while (l <= r) {
int mid = l + (r - l) / 2;
if (s[mid] <= key)
r = mid - 1;
else {
l = mid + 1;
if (index == -1 || s[index] >= s[mid])
index = mid;
}
}
return index;
}
bool nextpermutation(string& s)
{
int len = s.length(), i = len - 2;
while (i >= 0 && s[i] >= s[i + 1])
--i;
if (i < 0)
return false;
else {
int index = bsearch(s, i + 1, len - 1, s[i]);
swap(&s[i], &s[index]);
rev(s, i + 1, len - 1);
return true;
}
}
// Driver code
int main()
{
string s = { "gfg" };
bool val = nextpermutation(s);
if (val == false)
cout << "No Word Possible" << endl;
else
cout << s << endl;
return 0;
}
Java
//Java implementation
import java.io.*;
public class Main {
public static char[] nextPermutation(String s) {
// Convert the input string to a list of characters
char[] arr = s.toCharArray();
int n = arr.length;
int i = n - 2;
// Find the largest index i such that arr[i] < arr[i+1]
while (i >= 0 && arr[i] >= arr[i+1]) {
i--;
}
// If no such index exists, return "No next Permutation"
if (i < 0) {
String st = "No next Permutation possible";
char[] ar = st.toCharArray();
return ar;
}
int j = n - 1;
// Find the largest index j such that arr[i] < arr[j]
while (j >= 0 && arr[j] <= arr[i]) {
j--;
}
// Swap arr[i] and arr[j]
swap(arr, i, j);
//Reverse the sublist arr[start:end+1]
rev(arr, i+1, n-1);
return arr;
}
// Function to swap two numbers
private static void swap(char[] arr, int i, int j) {
char temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
//Function to reverse the array
private static void rev(char[] arr, int start, int end) {
while (start < end) {
swap(arr, start, end);
start++;
end--;
}
}
// Driver code
public static void main(String[] args)
{
String str2 = "gfg"; // Example 2
System.out.println(nextPermutation(str2));
}
}
Python3
def next_permutation(s: str) -> str:
# Convert the input string to a list of characters
arr = list(s)
n = len(arr)
i = n - 2
# Find the largest index i such that arr[i] < arr[i+1]
while i >= 0 and arr[i] >= arr[i+1]:
i -= 1
# If no such index exists, return "No next Permutation"
if i < 0:
return "No next Permutation possible"
j = n - 1
# Find the largest index j such that arr[i] < arr[j]
while j >= 0 and arr[j] <= arr[i]:
j -= 1
# Swap arr[i] and arr[j]
arr[i], arr[j] = arr[j], arr[i]
# Reverse the sublist arr[start:end+1]
rev(arr, i+1, n-1)
return ''.join(arr)
# Function to reverse the array
def rev(arr: list, start: int, end: int) -> None:
while start < end:
swap(arr, start, end)
start += 1
end -= 1
# Function to swap two numbers
def swap(arr: list, i: int, j: int) -> None:
temp = arr[i]
arr[i] = arr[j]
arr[j] = temp
# Driver code
if __name__ == '__main__':
s = "gfg"
print(next_permutation(s))
C#
using System;
class GFG {
public static char[] NextPermutation(string s) {
// Convert the input string to a char array
char[] arr = s.ToCharArray();
int n = arr.Length;
int i = n - 2;
// Find the largest index i such that arr[i] < arr[i+1]
while (i >= 0 && arr[i] >= arr[i+1]) {
i--;
}
// If no such index exists, return "No next Permutation"
if (i < 0) {
string st = "No next Permutation possible";
char[] ar = st.ToCharArray();
return ar;
}
int j = n - 1;
// Find the largest index j such that arr[i] < arr[j]
while (j >= 0 && arr[j] <= arr[i]) {
j--;
}
// Swap arr[i] and arr[j]
Swap(arr, i, j);
// Reverse the sublist arr[start:end+1]
Reverse(arr, i+1, n-1);
return arr;
}
// Function to swap two numbers
private static void Swap(char[] arr, int i, int j) {
char temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
// Function to reverse the array
private static void Reverse(char[] arr, int start, int end) {
while (start < end) {
Swap(arr, start, end);
start++;
end--;
}
}
// Driver code
public static void Main(string[] args) {
string str2 = "gfg"; // Example 2
Console.WriteLine(NextPermutation(str2));
}
}
JavaScript
function next_permutation(s) {
// Convert the input string to a list of characters
let arr = Array.from(s);
let n = arr.length;
let i = n - 2;
// Find the largest index i such that arr[i] < arr[i+1]
while (i >= 0 && arr[i] >= arr[i+1]) {
i--;
}
// If no such index exists, return "No next Permutation"
if (i < 0) {
return "No next Permutation possible";
}
let j = n - 1;
// Find the largest index j such that arr[i] < arr[j]
while (j >= 0 && arr[j] <= arr[i]) {
j--;
}
// Swap arr[i] and arr[j]
let temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
// Reverse the sublist arr[start:end+1]
rev(arr, i+1, n-1);
return arr.join('');
}
// Function to reverse the array
function rev(arr, start, end) {
while (start < end) {
swap(arr, start, end);
start++;
end--;
}
}
// Function to swap two numbers
function swap(arr, i, j) {
let temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
// Driver code
let s = "gfg";
console.log(next_permutation(s));
Time Complexity:
- In the worst case, the first step of next_permutation takes O(n) time.
- The binary search takes O(log n) time.
- The reverse takes O(n) time.
Overall time complexity is O(n). Where n is the length of the string.
Auxiliary Space is O(1), because no extra space is used.
Similar Reads
Lexicographically n-th permutation of a string
Given a string of length m containing lowercase alphabets only. You have to find the n-th permutation of string lexicographically. Examples: Input : str[] = "abc", n = 3 Output : Result = "bac" Explanation : All possible permutation in sorted order: abc, acb, bac, bca, cab, cba Input : str[] = "aba"
6 min read
Lexicographically smallest permutation of [1, N] based on given Binary string
Given a binary string S of size (N - 1), the task is to find the lexicographically smallest permutation P of the first N natural numbers such that for every index i, if S[i] equals '0' then P[i + 1] must be greater than P[i] and if S[i] equals '1' then P[i + 1] must be less than P[i]. Examples: Inpu
6 min read
Create lexicographically minimum String using given operation
Given a string s of length N consisting of digits from 0 to 9. Find the lexicographically minimum sequence that can be obtained from given string s by performing the given operations: Selecting any position i in the string and delete the digit 'd' at ith position, Insert min(d+1, 9) on any position
7 min read
Print all lexicographical greater permutations of a given string
Given a string S, print those permutations of string S which are lexicographically greater than S. If there is no such permutation of string, print -1. Examples: Input : BCA Output : CAB, CBA Explanation: Here, S = "BCA", and there are 2 strings "CAB, CBA" which are lexicographically greater than S.
13 min read
Lexicographically next string
Given a string, find lexicographically next string. Examples: Input : geeksOutput : geektThe last character 's' is changed to 't'.Input : raavzOutput : raawzSince we can't increase last character, we increment previous character.Input : zzzOutput : zzzaIf string is empty, we return 'a'. If string co
4 min read
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. Rec
11 min read
Lexicographically smallest permutation with no digits at Original Index
Given an integer N. The task is to find the lexicographically smallest permutation of integer of the form: 12345...N such that no digit occurs at the index as in the original number, i.e. if P1P2P3...PN is our permutation then Pi must not be equal to i. Note : N is greater than 1 and less than 10. E
7 min read
Print all permutations in sorted (lexicographic) order
Given a string s, print all unique permutations of the string in lexicographically sorted order.Examples:Input: "ABC"Output: ["ABC", "ACB", "BAC", "BCA", "CAB", "CBA"]Explanation: All characters are distinct, so there are 3! = 6 unique permutations, printed in sorted order.Input: "AAA"Output: ["AAA"
15+ min read
Lexicographically middle string
Given two strings a and b. Our task is to print any string which is greater than a(lexicographically) but smaller than b(lexicographically). If it is impossible to get such string, print -1; Examples: Input : a = "abg", b = "abj" Output : abh The string "abh" is lexicographically greater than "abg"
5 min read
Lexicographically first palindromic string
Rearrange the characters of the given string to form a lexicographically first palindromic string. If no such string exists display message "no palindromic string". Examples: Input : malayalam Output : aalmymlaa Input : apple Output : no palindromic string Simple Approach: 1. Sort the string charact
13 min read