Given a non-negative integer represented as a string s, find the smallest possible number that can be obtained by performing at most one swap of two digits.
Note: Output should not contain leading zeros.
Examples:
Input: s = "9625635"
Output: "2695635"
Explanation: Swapped the digits 9 and 2.Input: s = "1205763"
Output: "1025763"
Explanation: Swapped the digits 0 and 2.
[Naive Approach] Try Every Swap - O(n³) Time and O(1) Space
Since only one swap is allowed, try swapping every pair of digits and generate all possible valid numbers. Among all numbers obtained after at most one swap, keep track of the smallest one and return it. This guarantees finding the minimum possible number.
#include <bits/stdc++.h>
using namespace std;
// Return the smallest number possible by performing at most one swap.
string smallestNumber(string &s) {
string ans = s;
int n = s.size();
// Try every possible swap.
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
swap(s[i], s[j]);
// Ignore numbers with leading zero.
if (s[0] != '0' && s < ans) {
ans = s;
}
swap(s[i], s[j]);
}
}
return ans;
}
int main() {
string s = "9625635";
cout << smallestNumber(s);
return 0;
}
public class GFG {
// Return the smallest number possible by performing at most one swap.
static String smallestNumber(String s) {
String ans = s;
int n = s.length();
// Try every possible swap.
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
char[] arr = s.toCharArray();
char temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
String curr = new String(arr);
// Ignore numbers with leading zero.
if (curr.charAt(0) != '0' && curr.compareTo(ans) < 0) {
ans = curr;
}
}
}
return ans;
}
public static void main(String[] args) {
String s = "9625635";
System.out.println(smallestNumber(s));
}
}
# Return the smallest number possible by performing at most one swap.
def smallest_number(s):
ans = s
n = len(s)
# Try every possible swap.
for i in range(n):
for j in range(i + 1, n):
arr = list(s)
arr[i], arr[j] = arr[j], arr[i]
curr = "".join(arr)
# Ignore numbers with leading zero.
if curr[0] != '0' and curr < ans:
ans = curr
return ans
if __name__ == "__main__":
s = "9625635"
print(smallest_number(s))
using System;
class GFG
{
// Return the smallest number possible by performing at most one swap.
static string SmallestNumber(string s)
{
string ans = s;
int n = s.Length;
// Try every possible swap.
for (int i = 0; i < n; i++)
{
for (int j = i + 1; j < n; j++)
{
char[] arr = s.ToCharArray();
char temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
string curr = new string(arr);
// Ignore numbers with leading zero.
if (curr[0] != '0' && string.Compare(curr, ans) < 0)
{
ans = curr;
}
}
}
return ans;
}
static void Main()
{
string s = "9625635";
Console.WriteLine(SmallestNumber(s));
}
}
// Return the smallest number possible by performing at most one swap.
function smallestNumber(s) {
let ans = s;
const n = s.length;
// Try every possible swap.
for (let i = 0; i < n; i++) {
for (let j = i + 1; j < n; j++) {
const arr = s.split("");
[arr[i], arr[j]] = [arr[j], arr[i]];
const curr = arr.join("");
// Ignore numbers with leading zero.
if (curr[0] !== '0' && curr < ans) {
ans = curr;
}
}
}
return ans;
}
const s = "9625635";
console.log(smallestNumber(s));
Output
2695635
[Expected Approach] Greedy Swapping with Right-Side Minimum Digits - O(n) Time and O(n) Space
Since only one swap is allowed, the leftmost digit has the highest impact on the value of the number, so we try to make the leftmost possible position as small as possible.
We greedily reduce the leftmost possible digit. First, try to improve the leading digit using the smallest non-zero digit on its right. Otherwise, find the next leftmost position that can be improved.
Step-by-step Implementation:
- Store the index of the smallest digit available on the right of every position.
- Try to reduce the leading digit by swapping it with the smallest non-zero digit on its right.
- If such a swap exists, perform it and return the result.
- Otherwise, scan from left to right and find the first position that can be improved.
- Swap it with the smallest digit available on its right.
- Return the resulting string.
#include <bits/stdc++.h>
using namespace std;
// Return the smallest number possible by performing at most one swap.
string smallestNumber(string &s) {
int n = s.size();
vector<int> rightMin(n, -1);
int right = n - 1;
// Store the index of the best digit available
// on the right side for every position.
for (int i = n - 2; i >= 1; i--) {
if (s[i] >= s[right]) {
rightMin[i] = right;
} else {
if (s[i] == s[i + 1]) {
rightMin[i] = right;
} else {
rightMin[i] = -1;
right = i;
}
}
}
int smallest = -1;
// Find the smallest non-zero digit that can be
// swapped with the first digit.
for (int i = 1; i < n; i++) {
if (s[i] != '0') {
if (smallest == -1) {
if (s[i] < s[0]) {
smallest = i;
}
} else if (s[i] <= s[smallest]) {
smallest = i;
}
}
}
// If a smaller leading digit is available,
// perform the swap.
if (smallest != -1) {
swap(s[0], s[smallest]);
} else {
// Otherwise, find the first beneficial swap.
for (int i = 1; i < n; i++) {
if (rightMin[i] != -1 && s[i] != s[rightMin[i]]) {
swap(s[i], s[rightMin[i]]);
break;
}
}
}
return s;
}
int main() {
string s = "9625635";
cout << smallestNumber(s);
return 0;
}
import java.util.Arrays;
public class GFG {
// Return the smallest number possible by performing at most one swap.
static String smallestNumber(String s) {
int n = s.length();
int[] rightMin = new int[n];
Arrays.fill(rightMin, -1);
int right = n - 1;
// Store the index of the best digit available
// on the right side for every position.
for (int i = n - 2; i >= 1; i--) {
if (s.charAt(i) >= s.charAt(right)) {
rightMin[i] = right;
} else {
if (s.charAt(i) == s.charAt(i + 1)) {
rightMin[i] = right;
} else {
rightMin[i] = -1;
right = i;
}
}
}
int smallest = -1;
// Find the smallest non-zero digit that can be
// swapped with the first digit.
for (int i = 1; i < n; i++) {
if (s.charAt(i) != '0') {
if (smallest == -1) {
if (s.charAt(i) < s.charAt(0)) {
smallest = i;
}
} else if (s.charAt(i) <= s.charAt(smallest)) {
smallest = i;
}
}
}
char[] arr = s.toCharArray();
// If a smaller leading digit is available,
// perform the swap.
if (smallest != -1) {
char temp = arr[0];
arr[0] = arr[smallest];
arr[smallest] = temp;
} else {
// Otherwise, find the first beneficial swap.
for (int i = 1; i < n; i++) {
if (rightMin[i] != -1 && arr[i] != arr[rightMin[i]]) {
char temp = arr[i];
arr[i] = arr[rightMin[i]];
arr[rightMin[i]] = temp;
break;
}
}
}
return new String(arr);
}
public static void main(String[] args) {
String s = "9625635";
System.out.println(smallestNumber(s));
}
}
# Return the smallest number possible by performing at most one swap.
def smallest_number(s):
n = len(s)
right_min = [-1] * n
right = n - 1
# Store the index of the best digit available
# on the right side for every position.
for i in range(n - 2, 0, -1):
if s[i] >= s[right]:
right_min[i] = right
else:
if s[i] == s[i + 1]:
right_min[i] = right
else:
right = i
smallest = -1
# Find the smallest non-zero digit that can be
# swapped with the first digit.
for i in range(1, n):
if s[i] != '0':
if smallest == -1:
if s[i] < s[0]:
smallest = i
elif s[i] <= s[smallest]:
smallest = i
arr = list(s)
# If a smaller leading digit is available,
# perform the swap.
if smallest != -1:
arr[0], arr[smallest] = arr[smallest], arr[0]
else:
# Otherwise, find the first beneficial swap.
for i in range(1, n):
if right_min[i] != -1 and arr[i] != arr[right_min[i]]:
arr[i], arr[right_min[i]] = arr[right_min[i]], arr[i]
break
return "".join(arr)
if __name__ == "__main__":
s = "9625635"
print(smallest_number(s))
using System;
class GFG
{
// Return the smallest number possible by performing at most one swap.
static string SmallestNumber(string s)
{
int n = s.Length;
int[] rightMin = new int[n];
for (int i = 0; i < n; i++)
{
rightMin[i] = -1;
}
int right = n - 1;
// Store the index of the best digit available
// on the right side for every position.
for (int i = n - 2; i >= 1; i--)
{
if (s[i] >= s[right])
{
rightMin[i] = right;
}
else
{
if (s[i] == s[i + 1])
{
rightMin[i] = right;
}
else
{
right = i;
}
}
}
int smallest = -1;
// Find the smallest non-zero digit that can be
// swapped with the first digit.
for (int i = 1; i < n; i++)
{
if (s[i] != '0')
{
if (smallest == -1)
{
if (s[i] < s[0])
{
smallest = i;
}
}
else if (s[i] <= s[smallest])
{
smallest = i;
}
}
}
char[] arr = s.ToCharArray();
// If a smaller leading digit is available,
// perform the swap.
if (smallest != -1)
{
char temp = arr[0];
arr[0] = arr[smallest];
arr[smallest] = temp;
}
else
{
// Otherwise, find the first beneficial swap.
for (int i = 1; i < n; i++)
{
if (rightMin[i] != -1 && arr[i] != arr[rightMin[i]])
{
char temp = arr[i];
arr[i] = arr[rightMin[i]];
arr[rightMin[i]] = temp;
break;
}
}
}
return new string(arr);
}
static void Main()
{
string s = "9625635";
Console.WriteLine(SmallestNumber(s));
}
}
// Return the smallest number possible by performing at most one swap.
function smallestNumber(s) {
const n = s.length;
const rightMin = new Array(n).fill(-1);
let right = n - 1;
// Store the index of the best digit available
// on the right side for every position.
for (let i = n - 2; i >= 1; i--) {
if (s[i] >= s[right]) {
rightMin[i] = right;
} else {
if (s[i] === s[i + 1]) {
rightMin[i] = right;
} else {
right = i;
}
}
}
let smallest = -1;
// Find the smallest non-zero digit that can be
// swapped with the first digit.
for (let i = 1; i < n; i++) {
if (s[i] !== '0') {
if (smallest === -1) {
if (s[i] < s[0]) {
smallest = i;
}
} else if (s[i] <= s[smallest]) {
smallest = i;
}
}
}
const arr = s.split("");
// If a smaller leading digit is available,
// perform the swap.
if (smallest !== -1) {
[arr[0], arr[smallest]] = [arr[smallest], arr[0]];
} else {
// Otherwise, find the first beneficial swap.
for (let i = 1; i < n; i++) {
if (rightMin[i] !== -1 && arr[i] !== arr[rightMin[i]]) {
[arr[i], arr[rightMin[i]]] = [arr[rightMin[i]], arr[i]];
break;
}
}
}
return arr.join("");
}
const s = "9625635";
console.log(smallestNumber(s));
Output
2695635