Lexicographically Previous Permutation (original) (raw)

Last Updated : 3 Jun, 2026

Given a string **s representing a non-negative integer, find the lexicographically previous permutation of its digits. Each digit of s must be used exactly once, and the resulting number must not contain leading zeros.

**Examples:

**Input: s = "4321"
**Output: "4312"
**Explanation:The lexicographically previous permutation of "4321" is "4312".

**Input: s = "1234"
**Output: "-1"
**Explanation: The string "1234" is sorted in ascending order, so no previous permutation exists.

Try It Yourselfredirect icon

Table of Content

[Naive Approach] Generate All Permutations - O(|s| × |s|!) Time and O(|s|) Space

The idea is to generate all possible permutations of the digits of s using recursion (backtracking). For each permutation, we check whether it is valid,. Among all valid permutations, we keep track of the largest one. If no valid permutation exists, return “-1”.

C++ `

#include <bits/stdc++.h> using namespace std;

// Stores the largest valid permutation smaller than the original string string res;

// Backtracking function to generate all permutations void generate(string &s, string &curr, vector &used, string &original) {

// Base case: full permutation formed
if (curr.size() == s.size()) {

    // Skip leading zero numbers
    if (curr[0] == '0') return;

    // Check if valid candidate
    if (curr < original) {
        if (res == "-1" || curr > res)
            res = curr;
    }
    return;
}

// Try each unused digit
for (int i = 0; i < s.size(); i++) {

    if (used[i]) continue;

    used[i] = true;
    curr.push_back(s[i]);

    generate(s, curr, used, original);

    // Backtrack
    curr.pop_back();
    used[i] = false;
}

}

// Function to find lexicographically previous permutation string prevPermutation(string &s) {

//  reset global variable for each call
res = "-1";

string curr = "";
vector<bool> used(s.size(), false);

generate(s, curr, used, s);

return res;

} int main() {

string s = "4321";

cout << prevPermutation(s);

return 0;

}

Java

class GFG {

// Stores the largest valid permutation smaller than the original string
static String res = "-1";

// Function to generate all permutations of the string
static void generate(String s, StringBuilder curr,
                     boolean[] used, String original) {

    // If a complete permutation is formed
    if (curr.length() == s.length()) {

        String temp = curr.toString();

        // Ignore permutations with leading zeros
        if (temp.charAt(0) == '0')
            return;

        // Update answer if the current permutation is
        // smaller than the original and larger than
        // the previously found answer
        if (temp.compareTo(original) < 0) {
            if (res.equals("-1") || temp.compareTo(res) > 0)
                res = temp;
        }
        return;
    }

    // Try placing every unused digit at the current position
    for (int i = 0; i < s.length(); i++) {

        if (used[i])
            continue;

        used[i] = true;
        curr.append(s.charAt(i));

        generate(s, curr, used, original);

        // Backtrack
        curr.deleteCharAt(curr.length() - 1);
        used[i] = false;
    }
}

// Function to find the lexicographically previous permutation
static String prevPermutation(String s) {

    res = "-1";

    StringBuilder curr = new StringBuilder();
    boolean[] used = new boolean[s.length()];

    generate(s, curr, used, s);

    return res;
}

public static void main(String[] args) {

    String s = "4321";

    System.out.println(prevPermutation(s));
}

}

Python

Stores the largest valid permutation smaller than the original string

res = "-1"

Function to generate all permutations of the string

def generate(s, curr, used, original): global res

# If a complete permutation is formed
if len(curr) == len(s):

    temp = "".join(curr)

    # Ignore permutations with leading zeros
    if temp[0] == '0':
        return

    # Update answer if the current permutation is
    # smaller than the original and larger than
    # the previously found answer
    if temp < original:
        if res == "-1" or temp > res:
            res = temp
    return

# Try placing every unused digit at the current position
for i in range(len(s)):

    if used[i]:
        continue

    used[i] = True
    curr.append(s[i])

    generate(s, curr, used, original)

    # Backtrack
    curr.pop()
    used[i] = False

Function to find the lexicographically previous permutation

def prevPermutation(s): global res

res = "-1"

curr = []
used = [False] * len(s)

generate(s, curr, used, s)

return res

if name == "main":

s = "4321"

print(prevPermutation(s))

C#

using System; using System.Text;

class GFG { // Stores the largest valid permutation smaller than the original string static string res = "-1";

// Function to generate all permutations of the string
static void generate(string s, StringBuilder curr,
                     bool[] used, string original)
{
    // If a complete permutation is formed
    if (curr.Length == s.Length)
    {
        string temp = curr.ToString();

        // Ignore permutations with leading zeros
        if (temp[0] == '0')
            return;

        // Update answer if the current permutation is
        // smaller than the original and larger than
        // the previously found answer
        if (string.Compare(temp, original) < 0)
        {
            if (res == "-1" || string.Compare(temp, res) > 0)
                res = temp;
        }
        return;
    }

    // Try placing every unused digit at the current position
    for (int i = 0; i < s.Length; i++)
    {
        if (used[i])
            continue;

        used[i] = true;
        curr.Append(s[i]);

        generate(s, curr, used, original);

        // Backtrack
        curr.Length--;
        used[i] = false;
    }
}

// Function to find the lexicographically previous permutation
static string prevPermutation(string s)
{
    res = "-1";

    StringBuilder curr = new StringBuilder();
    bool[] used = new bool[s.Length];

    generate(s, curr, used, s);

    return res;
}

// Driver code
static void Main()
{
    string s = "4321";

    Console.WriteLine(prevPermutation(s));
}

}

JavaScript

// Stores the largest valid permutation smaller than the original string let res = "-1";

// Function to generate all permutations of the string function generate(s, curr, used, original) {

// If a complete permutation is formed
if (curr.length === s.length) {

    let temp = curr.join('');

    // Ignore permutations with leading zeros
    if (temp[0] === '0')
        return;

    // Update answer if the current permutation is
    // smaller than the original and larger than
    // the previously found answer
    if (temp < original) {
        if (res === "-1" || temp > res)
            res = temp;
    }
    return;
}

// Try placing every unused digit at the current position
for (let i = 0; i < s.length; i++) {

    if (used[i])
        continue;

    used[i] = true;
    curr.push(s[i]);

    generate(s, curr, used, original);

    // Backtrack
    curr.pop();
    used[i] = false;
}

}

// Function to find the lexicographically previous permutation function prevPermutation(s) {

res = "-1";

let curr = [];
let used = new Array(s.length).fill(false);

generate(s, curr, used, s);

return res;

}

// Driver code let s = "4321";

console.log(prevPermutation(s));

`

[Expected Approach] Previous Permutation - O(|s|) Time and O(1) Space

Instead of generating all permutations, we directly construct the previous permutation. We first find the pivot, the first index from the right where s[i] > s[i+1]. This is the point where the number can be reduced.

Consider the input: **s = "**534976"

**Step 1: Traverse from right and find the first index i such that s[i] > s[i + 1].

**Step 2: From the right side of pivot, find the largest digit smaller than pivot digit.

**Step 3: Swap the pivot digit with the selected digit.

**Step 4: Reverse the suffix after the pivot. Since the suffix is already in increasing order, reversing it makes it descending and gives the largest possible arrangement.

**Step 5: The resulting string is: 534967

Therefore, the lexicographically previous permutation of "534976" is: **534967

C++ `

#include <bits/stdc++.h> using namespace std;

string prevPermutation(string &s) { int n = s.size();

// Step 1: Find the pivot
int i = n - 2;
while (i >= 0 && s[i] <= s[i + 1]) {
    i--;
}

// No previous permutation exists
if (i < 0) {
    return "-1";
}

// Step 2: Find the largest digit smaller than s[i]
int j = -1;
for (int k = n - 1; k > i; k--) {

    if (s[k] < s[i]) {

        // Avoid leading zero
        if (i == 0 && s[k] == '0')
            continue;

        j = k;
        break;
    }
}

// No valid swap possible
if (j == -1) {
    return "-1";
}

// Step 3: Swap pivot with the chosen digit
swap(s[i], s[j]);

// Step 4: Reverse the suffix
reverse(s.begin() + i + 1, s.end());

return s;

}

int main() {

string s = "534976";

cout << prevPermutation(s) << endl;

return 0;

}

Java

class GFG {

static String prevPermutation(String s) {
    int n = s.length();

    // Step 1: Find the pivot
    int i = n - 2;
    while (i >= 0 && s.charAt(i) <= s.charAt(i + 1)) {
        i--;
    }

    // No previous permutation exists
    if (i < 0) {
        return "-1";
    }

    // Step 2: Find the largest digit smaller than s[i]
    int j = -1;
    for (int k = n - 1; k > i; k--) {

        if (s.charAt(k) < s.charAt(i)) {

            // Avoid leading zero
            if (i == 0 && s.charAt(k) == '0')
                continue;

            j = k;
            break;
        }
    }

    // No valid swap possible
    if (j == -1) {
        return "-1";
    }

    char[] arr = s.toCharArray();

    // Step 3: Swap pivot with the chosen digit
    char temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;

    // Step 4: Reverse the suffix
    int left = i + 1, right = n - 1;
    while (left < right) {
        temp = arr[left];
        arr[left] = arr[right];
        arr[right] = temp;
        left++;
        right--;
    }

    return new String(arr);
}

public static void main(String[] args) {

    String s = "534976";

    System.out.println(prevPermutation(s));
}

}

Python

def prevPermutation(s): n = len(s) s = list(s)

# Step 1: Find the pivot
i = n - 2
while i >= 0 and s[i] <= s[i + 1]:
    i -= 1

# No previous permutation exists
if i < 0:
    return "-1"

# Step 2: Find the largest digit smaller than s[i]
j = -1
for k in range(n - 1, i, -1):

    if s[k] < s[i]:

        # Avoid leading zero
        if i == 0 and s[k] == '0':
            continue

        j = k
        break

# No valid swap possible
if j == -1:
    return "-1"

# Step 3: Swap pivot with the chosen digit
s[i], s[j] = s[j], s[i]

# Step 4: Reverse the suffix
s[i + 1:] = reversed(s[i + 1:])

return "".join(s)

if name == "main":

s = "534976"

print(prevPermutation(s))

C#

using System;

class GFG { static string prevPermutation(string s) { int n = s.Length;

    // Step 1: Find the pivot
    int i = n - 2;
    while (i >= 0 && s[i] <= s[i + 1])
    {
        i--;
    }

    // No previous permutation exists
    if (i < 0)
    {
        return "-1";
    }

    // Step 2: Find the largest digit smaller than s[i]
    int j = -1;
    for (int k = n - 1; k > i; k--)
    {
        if (s[k] < s[i])
        {
            // Avoid leading zero
            if (i == 0 && s[k] == '0')
                continue;

            j = k;
            break;
        }
    }

    // No valid swap possible
    if (j == -1)
    {
        return "-1";
    }

    char[] arr = s.ToCharArray();

    // Step 3: Swap pivot with the chosen digit
    char temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;

    // Step 4: Reverse the suffix
    Array.Reverse(arr, i + 1, n - i - 1);

    return new string(arr);
}

static void Main()
{
    string s = "534976";

    Console.WriteLine(prevPermutation(s));
}

}

JavaScript

function prevPermutation(s) { let n = s.length; s = s.split('');

// Step 1: Find the pivot
let i = n - 2;
while (i >= 0 && s[i] <= s[i + 1]) {
    i--;
}

// No previous permutation exists
if (i < 0) {
    return "-1";
}

// Step 2: Find the largest digit smaller than s[i]
let j = -1;
for (let k = n - 1; k > i; k--) {

    if (s[k] < s[i]) {

        // Avoid leading zero
        if (i === 0 && s[k] === '0')
            continue;

        j = k;
        break;
    }
}

// No valid swap possible
if (j === -1) {
    return "-1";
}

// Step 3: Swap pivot with the chosen digit
[s[i], s[j]] = [s[j], s[i]];

// Step 4: Reverse the suffix
let left = i + 1, right = n - 1;
while (left < right) {
    [s[left], s[right]] = [s[right], s[left]];
    left++;
    right--;
}

return s.join('');

}

// Driver code let s = "534976"; console.log(prevPermutation(s));

`