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
Table of Content
[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
#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;
}
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));
}
}
# 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))
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));
}
}
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
#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;
}
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));
}
}
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))
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));
}
}
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