Next higher number using atmost one swap operation

Last Updated : 4 Jul, 2026

Given a non-negative number num represented as a string, apply at most one swap operation on any two of its digits to obtain the next higher number.

If it is impossible to form a higher number, return "-1".

Examples: 

Input: num = "768"
Output: "786"
Explanation: There is no higher number than 333.

Input: num = "333"
Output: "-1"
Explanation: There is no higher number than 333.

Try It Yourself
redirect icon

[Naive Approach] Brute Force Swap Check - O(n² × n) Time and O(n) Space

Try swapping every pair of digits. For each swap, check if resulting string is greater than original. Keep the smallest valid result.

  • For i from 0 to n-1
  • For j from i+1 to n-1
  • Create copy of string and swap digits at i and j
  • If swapped string > original, update answer with minimum
  • Return answer or -1 if none found
C++
#include <bits/stdc++.h>
using namespace std;

string nextHigher(string &num) {
    int n = num.size();
    string ans = "";

    // Try every possible swap
    for (int i = 0; i < n; i++) {
        for (int j = i + 1; j < n; j++) {
            string curr = num;
            swap(curr[i], curr[j]);

            // Check if it forms a higher number
            if (curr > num) {
                // Keep the smallest higher number
                if (ans.empty() || curr < ans) {
                    ans = curr;
                }
            }
        }
    }

    return ans.empty() ? "-1" : ans;
}

int main() {
    string num="768";

    cout << nextHigher(num);

    return 0;
}
Java
import java.util.*;

class GfG {
    
    static String nextHigher(String num) {
        int n = num.length();
        String ans = "";
        
        // Try every possible swap
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                char[] curr = num.toCharArray();
                char temp = curr[i];
                curr[i] = curr[j];
                curr[j] = temp;
                String currStr = new String(curr);
                
                // Check if it forms a higher number
                if (currStr.compareTo(num) > 0) {
                    // Keep the smallest higher number
                    if (ans.isEmpty() || currStr.compareTo(ans) < 0) {
                        ans = currStr;
                    }
                }
            }
        }
        
        return ans.isEmpty() ? "-1" : ans;
    }
    
    public static void main(String[] args) {
        String num = "768";
        
        System.out.println(nextHigher(num));
    }
}
Python
# Returns the next higher number with same digits
def nextHigher(num):
    n = len(num)
    ans = ""
    
    # Try every possible swap
    for i in range(n):
        for j in range(i + 1, n):
            curr = list(num)
            curr[i], curr[j] = curr[j], curr[i]
            curr_str = ''.join(curr)
            
            # Check if it forms a higher number
            if curr_str > num:
                # Keep the smallest higher number
                if ans == "" or curr_str < ans:
                    ans = curr_str
    
    return "-1" if ans == "" else ans

if __name__ == "__main__":
    num = "768"
    
    print(nextHigher(num))
C#
using System;

class GfG {
    
    static string nextHigher(string num) {
        int n = num.Length;
        string ans = "";
        
        // Try every possible swap
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                char[] curr = num.ToCharArray();
                char temp = curr[i];
                curr[i] = curr[j];
                curr[j] = temp;
                string currStr = new string(curr);
                
                // Check if it forms a higher number
                if (string.Compare(currStr, num) > 0) {
                    // Keep the smallest higher number
                    if (ans == "" || string.Compare(currStr, ans) < 0) {
                        ans = currStr;
                    }
                }
            }
        }
        
        return ans == "" ? "-1" : ans;
    }
    
    static void Main(string[] args) {
        string num = "768";
        
        Console.WriteLine(nextHigher(num));
    }
}
JavaScript
function nextHigher(num) {
    const n = num.length;
    let ans = "";
    
    // Try every possible swap
    for (let i = 0; i < n; i++) {
        for (let j = i + 1; j < n; j++) {
            let curr = num.split('');
            [curr[i], curr[j]] = [curr[j], curr[i]];
            let currStr = curr.join('');
            
            // Check if it forms a higher number
            if (currStr > num) {
                // Keep the smallest higher number
                if (ans === "" || currStr < ans) {
                    ans = currStr;
                }
            }
        }
    }
    
    return ans === "" ? "-1" : ans;
}

const num = "768";

console.log(nextHigher(num));

Output
786

[Expected Approach] Next Permutation Logic - O(n) Time and O(1) Space

Find the rightmost digit that can be swapped to get a larger number. Then swap with smallest larger digit on right. This gives next lexicographically larger permutation.

  • Traverse from right to left to find first digit smaller than digit on its right
  • If no such digit found, return -1
  • Find smallest digit on right of pivot that is greater than pivot
  • Swap pivot with that digit
  • Return the resulting number
C++
#include <bits/stdc++.h>
using namespace std;

string nextHigher(string num)
{
    int l = num.size();
    int posRMax = l - 1;
    int index = -1;

    // Loop from right to left to find the
    // first digit smaller than the max digit
    // seen so far
    for (int i = l - 2; i >= 0; i--)
    {
        if (num[i] >= num[posRMax])
        {
            posRMax = i;
        }
        else
        {
            index = i;
            break;
        }
    }

    if (index == -1)
    {
        return "-1";
    }

    int greatSmallDgt = -1;

    // Find the smallest digit to the right
    // of index that is strictly greater than
    // num[index]
    for (int i = l - 1; i > index; i--)
    {
        if (num[i] > num[index])
        {
            if (greatSmallDgt == -1)
            {
                greatSmallDgt = i;
            }
            else if (num[i] <= num[greatSmallDgt])
            {
                greatSmallDgt = i;
            }
        }
    }

    // Swap the identified pivot with
    // the optimal right-side digit
    char temp = num[index];
    num[index] = num[greatSmallDgt];
    num[greatSmallDgt] = temp;

    return num;
}

int main()
{
    string num = "768";

    cout << nextHigher(num);

    return 0;
}
Java
import java.util.*;

class GfG {
    
    static String nextHigher(String num) {
        int l = num.length();
        int posRMax = l - 1;
        int index = -1;
        
        // Loop from right to left to find the
        // first digit smaller than the max digit
        // seen so far
        for (int i = l - 2; i >= 0; i--) {
            if (num.charAt(i) >= num.charAt(posRMax)) {
                posRMax = i;
            } else {
                index = i;
                break;
            }
        }
        
        if (index == -1) {
            return "-1";
        }
        
        int greatSmallDgt = -1;
        
        // Find the smallest digit to the right
        // of index that is strictly greater than
        // num[index]
        for (int i = l - 1; i > index; i--) {
            if (num.charAt(i) > num.charAt(index)) {
                if (greatSmallDgt == -1) {
                    greatSmallDgt = i;
                } else if (num.charAt(i) <= num.charAt(greatSmallDgt)) {
                    greatSmallDgt = i;
                }
            }
        }
        
        // Swap the identified pivot with
        // the optimal right-side digit
        char[] chars = num.toCharArray();
        char temp = chars[index];
        chars[index] = chars[greatSmallDgt];
        chars[greatSmallDgt] = temp;
        num = new String(chars);
        
        return num;
    }
    
    public static void main(String[] args) {
        String num = "768";
        
        System.out.println(nextHigher(num));
    }
}
Python
def nextHigher(num):
    l = len(num)
    posRMax = l - 1
    index = -1
    
    # Loop from right to left to find the
    # first digit smaller than the max digit
    # seen so far
    for i in range(l - 2, -1, -1):
        if num[i] >= num[posRMax]:
            posRMax = i
        else:
            index = i
            break
    
    if index == -1:
        return "-1"
    
    greatSmallDgt = -1
    
    # Find the smallest digit to the right
    # of index that is strictly greater than
    # num[index]
    for i in range(l - 1, index, -1):
        if num[i] > num[index]:
            if greatSmallDgt == -1:
                greatSmallDgt = i
            elif num[i] <= num[greatSmallDgt]:
                greatSmallDgt = i
    
    # Swap the identified pivot with
    # the optimal right-side digit
    num_list = list(num)
    num_list[index], num_list[greatSmallDgt] = num_list[greatSmallDgt], num_list[index]
    
    return ''.join(num_list)

if __name__ == "__main__":
    num = "768"
    
    print(nextHigher(num))
C#
using System;

class GfG {
    
    static string nextHigher(string num) {
        int l = num.Length;
        int posRMax = l - 1;
        int index = -1;
        
        // Loop from right to left to find the
        // first digit smaller than the max digit
        // seen so far
        for (int i = l - 2; i >= 0; i--) {
            if (num[i] >= num[posRMax]) {
                posRMax = i;
            } else {
                index = i;
                break;
            }
        }
        
        if (index == -1) {
            return "-1";
        }
        
        int greatSmallDgt = -1;
        
        // Find the smallest digit to the right
        // of index that is strictly greater than
        // num[index]
        for (int i = l - 1; i > index; i--) {
            if (num[i] > num[index]) {
                if (greatSmallDgt == -1) {
                    greatSmallDgt = i;
                } else if (num[i] <= num[greatSmallDgt]) {
                    greatSmallDgt = i;
                }
            }
        }
        
        // Swap the identified pivot with
        // the optimal right-side digit
        char[] chars = num.ToCharArray();
        char temp = chars[index];
        chars[index] = chars[greatSmallDgt];
        chars[greatSmallDgt] = temp;
        num = new string(chars);
        
        return num;
    }
    
    static void Main(string[] args) {
        string num = "768";
        
        Console.WriteLine(nextHigher(num));
    }
}
JavaScript
function nextHigher(num) {
    const l = num.length;
    let posRMax = l - 1;
    let index = -1;
    
    // Loop from right to left to find the
    // first digit smaller than the max digit
    // seen so far
    for (let i = l - 2; i >= 0; i--) {
        if (num[i] >= num[posRMax]) {
            posRMax = i;
        } else {
            index = i;
            break;
        }
    }
    
    if (index === -1) {
        return "-1";
    }
    
    let greatSmallDgt = -1;
    
    // Find the smallest digit to the right
    // of index that is strictly greater than
    // num[index]
    for (let i = l - 1; i > index; i--) {
        if (num[i] > num[index]) {
            if (greatSmallDgt === -1) {
                greatSmallDgt = i;
            } else if (num[i] <= num[greatSmallDgt]) {
                greatSmallDgt = i;
            }
        }
    }
    
    // Swap the identified pivot with
    // the optimal right-side digit
    let chars = num.split('');
    [chars[index], chars[greatSmallDgt]] = [chars[greatSmallDgt], chars[index]];
    
    return chars.join('');
}

const num = "768";

console.log(nextHigher(num));

Output
786
Comment