AlgoMaster Logo

Maximum Swap

mediumFrequencyUpdated September 21, 2026

Understanding the Problem

We have a non-negative integer, and we can swap two of its digits at most once to make the number as large as possible. If the number is already the largest it can be, we leave it alone.

Digit placement drives the value. A larger digit earlier in the number contributes far more to the total than the same digit later, because each position to the left carries a higher power of ten. So we want to find the leftmost digit that has a bigger digit somewhere to its right, and swap it with the largest such digit. When that larger digit appears more than once, we swap with its rightmost occurrence. That keeps the bigger digit at the same left position while pushing the displaced smaller digit as far right as possible, where it costs the least.

With num = 1993, the digit 1 at position 0 has a 9 to its right. There are two 9s, at positions 1 and 2. We swap with the last 9 (position 2), giving 9913. Swapping with either 9 puts a 9 at the front, but swapping with the later one leaves a 9 at position 1 instead of a 1.

Key Constraints:

  • 0 <= num <= 10^8 means the number has at most 9 digits. With d <= 9, even an O(d^2) brute force over digit pairs (at most 36 pairs) runs instantly. The difficulty here is getting the tie-breaking correct, not the running time.

Approach 1: Brute Force (Try All Swaps)

Intuition

Try every possible pair of positions to swap, compute the resulting number, and keep the maximum. With at most 9 digits, the number of pairs is at most C(9, 2) = 36, so checking all of them is cheap.

For each pair (i, j), swap the digits, convert back to a number, compare against the running maximum, then swap back to restore the array for the next pair.

Algorithm

  1. Convert the number to a character array (or string of digits).
  2. Initialize maxNum = num (the original number, in case no swap helps).
  3. For each pair of indices i and j where i < j:
    • Swap digits[i] and digits[j].
    • Convert the array back to a number.
    • Update maxNum if this number is larger.
    • Swap back to restore the original array.
  4. Return maxNum.

Visualization and Code

Loading animation...

The brute force ignores the structure of the problem. The next approach uses the fact that a larger digit belongs as far left as possible to pick the single best swap in one pass.

Approach 2: Greedy (Last Occurrence Array)

Intuition

To maximize the number, we want the largest available digit as far left as possible. Scan from left to right, and at each position check whether a bigger digit appears anywhere to its right. The first position where that holds is the one to fix: we have only one swap, so spending it on the most significant improvable position gives the largest gain. Once we make that swap, we return.

When the bigger digit appears more than once to the right, we swap with its rightmost occurrence. Consider 27939. At position 0 the digit is 2, and 9 appears at positions 2 and 4. Swapping with position 4 gives 97932; swapping with position 2 gives 97239. Both put a 9 at the front, but the rightmost choice leaves the displaced 2 at position 4, where it contributes least.

The algorithm: precompute the last occurrence of each digit (0-9), then scan left to right. At each position, check whether any digit strictly larger than the current one has its last occurrence to the right. If so, swap and return.

Algorithm

  1. Convert the number to a character array.
  2. Create an array lastIndex of size 10 (for digits 0-9), storing the last position where each digit appears.
  3. Scan the digit array from left to right. At each position i:
    • Check digits 9 down to digits[i] + 1 (strictly larger digits).
    • If lastIndex[d] is greater than i, swap digits[i] with digits[lastIndex[d]].
    • Convert back to a number and return immediately.
  4. If no swap was made, the number is already maximized. Return it as-is.

Visualization and Code

Loading animation...