Given a string s and an integer k, the task is to find the maximum possible number by performing swap operations on the digits of s at most k times.
Examples:
Input: s = "7599", k = 2
Output: 9975
Explanation: Two Swaps can make input 7599 to 9975. First swap 9 with 5 so number becomes 7995, then swap 9 with 7 so number becomes 9975Input: s = "1234567", k = 4
Output: 7654321
Explanation: Three swaps can make the input 1234567 to 7654321. First swap 1 with 7, then swap 2 with 6 and finally swap 3 with 5.Input: s = "76543", k = 1
Output: 76543
Explanation: No swap is required.
Table of Content
[Approach 1] Using Recursion - O((n^2)^k) Time and O(k) Space
The idea is to generate the maximum possible number by performing at most
kswaps on the given string. We iterate through all pairs of characters and swap them if it results in a larger number. After each swap, we recursively call the function with one fewer swap left. The algorithm backtracks after each swap to explore all possible combinations, and the largest number found is returned as the result.
// C++ Implementation to Find the maximum
// number possible after at most `k` swaps
// using Recursion
#include <bits/stdc++.h>
using namespace std;
string findMax(string &s, int k) {
// Base case: If no swaps are allowed
if (k == 0) {
return s;
}
int n = s.size();
string ans = s;
// Iterate through all character pairs
for (int i = 0; i < n - 1; i++) {
for (int j = i + 1; j < n; j++) {
// Swap only if s[j] > s[i]
if (s[i] < s[j]) {
// Perform the swap
swap(s[i], s[j]);
// Recur to check maximum with
// one less swap allowed
ans = max(ans, findMax(s, k - 1));
// Backtrack to original state
swap(s[i], s[j]);
}
}
}
return ans;
}
string findMaximumNum(string s, int k) {
// Wrapper function to find result
return findMax(s, k);
}
int main() {
string s = "7599";
int k = 2;
cout << findMaximumNum(s, k) << endl;
return 0;
}
// Java Implementation to Find the maximum
// number possible after at most `k` swaps
// using Recursion
import java.util.*;
class GfG {
static String findMax(String s, int k) {
// Base case: If no swaps are allowed
if (k == 0) {
return s;
}
int n = s.length();
String ans = s;
// Iterate through all character pairs
for (int i = 0; i < n - 1; i++) {
for (int j = i + 1; j < n; j++) {
// Swap only if s[j] > s[i]
if (s.charAt(i) < s.charAt(j)) {
// Perform the swap
s = swap(s, i, j);
// Recur to check maximum with
// one less swap allowed
String recResult = findMax(s, k - 1);
if (recResult.compareTo(ans) > 0) {
ans = recResult;
}
// Backtrack to original state
s = swap(s, i, j);
}
}
}
return ans;
}
static String findMaximumNum(String s, int k) {
// Wrapper function to find result
return findMax(s, k);
}
static String swap(String s, int i, int j) {
// Swap characters at indices i and j
char[] arr = s.toCharArray();
char temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
return new String(arr);
}
public static void main(String[] args) {
String s = "7599";
int k = 2;
System.out.println(findMaximumNum(s, k));
}
}
# Python Implementation to Find the maximum
# number possible after at most `k` swaps
# using Recursion
def findMax(s, k):
# Base case: If no swaps are allowed
if k == 0:
return s
n = len(s)
ans = s
# Iterate through all character pairs
for i in range(n - 1):
for j in range(i + 1, n):
# Swap only if s[j] > s[i]
if s[i] < s[j]:
# Perform the swap
swapped = list(s)
swapped[i], swapped[j] = swapped[j], swapped[i]
swapped = ''.join(swapped)
# Recur to check maximum with
# one less swap allowed
rec_result = findMax(swapped, k - 1)
if rec_result > ans:
ans = rec_result
return ans
def findMaximumNum(s, k):
# Wrapper function to find result
return findMax(s, k)
if __name__ == "__main__":
s = "7599"
k = 2
print(findMaximumNum(s, k))
// C# Implementation to Find the maximum
// number possible after at most `k` swaps
// using Recursion
using System;
class GfG {
static string findMax(string s, int k) {
// Base case: If no swaps are allowed
if (k == 0) {
return s;
}
int n = s.Length;
string ans = s;
// Iterate through all character pairs
for (int i = 0; i < n - 1; i++) {
for (int j = i + 1; j < n; j++) {
// Swap only if s[j] > s[i]
if (s[i] < s[j]) {
// Perform the swap
s = swap(s, i, j);
// Recur to check maximum with
// one less swap allowed
string recResult = findMax(s, k - 1);
if (string.Compare(recResult, ans)
> 0) {
ans = recResult;
}
// Backtrack to original state
s = swap(s, i, j);
}
}
}
return ans;
}
static string findMaximumNum(string s, int k) {
// Wrapper function to find result
return findMax(s, k);
}
static string swap(string s, int i, int j) {
// Swap characters at indices i and j
char[] arr = s.ToCharArray();
char temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
return new string(arr);
}
static void Main(string[] args) {
string s = "7599";
int k = 2;
Console.WriteLine(findMaximumNum(s, k));
}
}
// JavaScript Implementation to Find the maximum
// number possible after at most `k` swaps
// using Recursion
function findMax(s, k) {
// Base case: If no swaps are allowed
if (k === 0) {
return s;
}
const n = s.length;
let ans = s;
// Iterate through all character pairs
for (let i = 0; i < n - 1; i++) {
for (let j = i + 1; j < n; j++) {
// Swap only if s[j] > s[i]
if (s[i] < s[j]) {
// Perform the swap
let swapped = s.split("");
[swapped[i], swapped[j]] =
[ swapped[j], swapped[i] ];
swapped = swapped.join("");
// Recur to check maximum with
// one less swap allowed
const recResult = findMax(swapped, k - 1);
if (recResult > ans) {
ans = recResult;
}
}
}
}
return ans;
}
function findMaximumNum(s, k) {
// Wrapper function to find result
return findMax(s, k);
}
//driver code
const s = "7599";
const k = 2;
console.log(findMaximumNum(s, k));
Output
9975
Time Complexity: O((n^2)^k), where n is the length of the string and k is the maximum number of swaps. For each recursion, O(n^2) operations are performed, and there are k levels of recursion).
Auxiliary Space: O(k), for the recursion stack.
[Approach 2] Swap the Max Digit - O((n^2)^k) Time and O(k) Space
The idea is to recursively iterate through the string, finding the maximum digit for the current position, and swapping it with a larger digit later in the string. The algorithm uses a backtracking technique, meaning after each swap, it recurses to explore further swaps and then undoes the swap (backtracks). This process continues until no swaps are left or the maximum number is achieved.
// C++ Implementation to Find the maximum
// number possible after at most `k` swaps
// using Recursion with focused digit placement.
#include <bits/stdc++.h>
using namespace std;
// Function to keep the maximum result
void match(string &curr, string &result) {
// If current number is larger, update result
if (curr > result) {
result = curr;
}
}
// Function to set highest possible digits at given index
void setDigit(string &s, int index, string &res, int k) {
// Base case: If no swaps left or index reaches
// the last character, update result
if (k == 0 || index == s.size() - 1) {
match(s, res);
return;
}
int maxDigit = 0;
// Finding maximum digit for placing at given index
for (int i = index; i < s.size(); i++) {
maxDigit = max(maxDigit, s[i] - '0');
}
// If the digit at current index is already max
if (s[index] - '0' == maxDigit) {
setDigit(s, index + 1, res, k);
return;
}
// Try swapping with the maximum digit found
for (int i = index + 1; i < s.size(); i++) {
// If max digit is found at current position
if (s[i] - '0' == maxDigit) {
// Swap to get the max digit at the required index
swap(s[index], s[i]);
// Call the recursive function to set the next digit
setDigit(s, index + 1, res, k - 1);
// Backtrack: swap the digits back
swap(s[index], s[i]);
}
}
}
// Function to find the largest number after k swaps
string findMaximumNum(string s, int k) {
string res = s;
setDigit(s, 0, res, k);
// Returning the result
return res;
}
int main() {
string s = "7599";
int k = 2;
cout << findMaximumNum(s, k) << endl;
return 0;
}
// Java Implementation to Find the maximum
// number possible after at most `k` swaps
// using Recursion with focused digit placement.
class GfG {
// Function to keep the maximum result
static void match(String curr,
StringBuilder result) {
// If current number is larger, update result
if (curr.compareTo(result.toString()) > 0) {
result.replace(0, result.length(), curr);
}
}
// Function to set highest possible digits at given index
static void setDigit(StringBuilder s,
int index, StringBuilder res, int k) {
// Base case: If no swaps left or index reaches
// the last character, update result
if (k == 0 || index == s.length() - 1) {
match(s.toString(), res);
return;
}
int maxDigit = 0;
// Finding maximum digit for placing at given index
for (int i = index; i < s.length(); i++) {
maxDigit = Math.max(maxDigit, s.charAt(i) - '0');
}
// If the digit at current index is already max
if (s.charAt(index) - '0' == maxDigit) {
setDigit(s, index + 1, res, k);
return;
}
// Try swapping with the maximum digit found
for (int i = index + 1; i < s.length(); i++) {
// If max digit is found at current position
if (s.charAt(i) - '0' == maxDigit) {
// Swap to get the max digit at the required index
char temp = s.charAt(index);
s.setCharAt(index, s.charAt(i));
s.setCharAt(i, temp);
// Call the recursive function to set
// the next digit
setDigit(s, index + 1, res, k - 1);
// Backtrack: swap the digits back
s.setCharAt(i, s.charAt(index));
s.setCharAt(index, temp);
}
}
}
// Function to find the largest number after k swaps
static String findMaximumNum(String s, int k) {
StringBuilder res = new StringBuilder(s);
setDigit(new StringBuilder(s), 0, res, k);
// Returning the result
return res.toString();
}
public static void main(String[] args) {
String s = "7599";
int k = 2;
System.out.println(findMaximumNum(s, k));
}
}
# Python Implementation to Find the maximum
# number possible after at most `k` swaps
# using Recursion with focused digit placement.
# Function to keep the maximum result
def match(curr, res):
# If current number is larger, update result
if curr > res:
res = curr
return res
# Function to set highest possible digits
# at given index
def setDigit(s, index, res, k):
# Base case: If no swaps left or index reaches
# the last character, update result
if k == 0 or index == len(s) - 1:
res = match(s, res)
return res
maxDigit = 0
# Finding maximum digit for placing at given index
for i in range(index, len(s)):
maxDigit = max(maxDigit, int(s[i]))
# If the digit at current index is already max
if int(s[index]) == maxDigit:
res = setDigit(s, index + 1, res, k)
return res
# Try swapping with the maximum digit found
for i in range(index + 1, len(s)):
# If max digit is found at current position
if int(s[i]) == maxDigit:
# Swap to get the max digit at the required index
s = swap(s, index, i)
# Call the recursive function to set the next digit
res = setDigit(s, index + 1, res, k - 1)
# Backtrack: swap the digits back
s = swap(s, index, i)
return res
# Function to swap characters in the string
def swap(s, i, j):
# Convert string to list for mutation,
# then back to string
s_list = list(s)
s_list[i], s_list[j] = s_list[j], s_list[i]
return ''.join(s_list)
# Function to find the largest number after k swaps
def findMaximumNum(s, k):
res = s
res = setDigit(s, 0, res, k)
# Returning the result
return res
if __name__ == "__main__":
s = "7599"
k = 2
print(findMaximumNum(s, k))
// C# Implementation to Find the maximum
// number possible after at most `k` swaps
// using Recursion with focused digit placement.
using System;
class GfG {
// Function to keep the maximum result
static void match(string curr, ref string result) {
// If current number is larger, update result
if (String.Compare(curr, result) > 0) {
result = curr;
}
}
// Function to set highest possible digits at given
// index
static void setDigit(ref string s, int index,
ref string res, int k) {
// Base case: If no swaps left or index reaches
// the last character, update result
if (k == 0 || index == s.Length - 1) {
match(s, ref res);
return;
}
int maxDigit = 0;
// Finding maximum digit for placing at given index
for (int i = index; i < s.Length; i++) {
maxDigit = Math.Max(maxDigit, s[i] - '0');
}
// If the digit at current index is already max
if (s[index] - '0' == maxDigit) {
setDigit(ref s, index + 1, ref res, k);
return;
}
// Try swapping with the maximum digit found
for (int i = index + 1; i < s.Length; i++) {
// If max digit is found at current position
if (s[i] - '0' == maxDigit) {
// Swap to get the max digit at the required
// index
char[] arr = s.ToCharArray();
char temp = arr[index];
arr[index] = arr[i];
arr[i] = temp;
s = new string(arr);
// Call the recursive function to set the
// next digit
setDigit(ref s, index + 1, ref res, k - 1);
// Backtrack: swap the digits back
arr[i] = arr[index];
arr[index] = temp;
s = new string(arr);
}
}
}
// Function to find the largest number after k swaps
static string findMaximumNum(string s, int k) {
string res = s;
setDigit(ref s, 0, ref res, k);
// Returning the result
return res;
}
static void Main() {
string s = "7599";
int k = 2;
Console.WriteLine(findMaximumNum(s, k));
}
}
// JavaScript Implementation to Find the maximum
// number possible after at most `k` swaps
// using Recursion with focused digit placement.
// Function to keep the maximum result
function match(curr, res) {
// If current number is larger, update result
if (curr > res) {
res = curr;
}
return res;
}
// Function to set highest possible digits at given index
function setDigit(s, index, res, k) {
// Base case: If no swaps left or index reaches
// the last character, update result
if (k === 0 || index === s.length - 1) {
res = match(s, res);
return res;
}
let maxDigit = 0;
// Finding maximum digit for placing at given index
for (let i = index; i < s.length; i++) {
maxDigit = Math.max(maxDigit, s[i] - "0");
}
// If the digit at current index is already max
if (s[index] - "0" === maxDigit) {
res = setDigit(s, index + 1, res, k);
return res;
}
// Try swapping with the maximum digit found
for (let i = index + 1; i < s.length; i++) {
// If max digit is found at current position
if (s[i] - "0" === maxDigit) {
// Swap to get the max digit at the required
// index
s = swap(s, index, i);
// Call the recursive function to set the next
// digit
res = setDigit(s, index + 1, res, k - 1);
// Backtrack: swap the digits back
s = swap(s, index, i);
}
}
return res;
}
// Function to swap characters in the string
function swap(s, i, j) {
let arr = s.split("");
let temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
return arr.join("");
}
// Function to find the largest number after k swaps
function findMaximumNum(s, k) {
let res = s;
res = setDigit(s, 0, res, k);
// Returning the result
return res;
}
// driver code
let s = "7599";
let k = 2;
console.log(findMaximumNum(s, k));
Output
9975
Time Complexity: O(n^2 ^ k), where n is the length of the string and k is the maximum number of swaps. In the worst case, the recursion can go as deep as k. Therefore, the total time complexity can be approximated as O(n^2 ^ k)
Auxiliary Space: O(k), due to recursion stack.