Largest smaller number possible using only one swap operation

Given a non-negative number N in the form of string. The task is to apply at most one swap operation on the number N so that the resultant is smaller than N and is the largest such number.

Examples:

Input :str = "12435"
Output : 12345
Although the number 12354 will be the 
largest smaller number from 12435. But 
it is not possible to make it using only
one swap. So swap 4 and 3 and get 12345.

Input : 34123567
Output : 33124567
We swap 4 with 3 (on its right side) to
get the largest smaller number.

Input : str = " 12345"
Output : -1
Digits are in increasing order. So it 
is not possible to make a smaller number 
from it.

Recommended: Please solve it on “PRACTICE” first, before moving on to the solution.

  1. Start traversing from right, find a digit is which is greater than one of the digits on its right. Let this index such element be index.
  2. Then find another index on right of str[index] which holds the greatest value smaller than str[index].
  3. Swap two values found above.

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to find the largest smaller  
// number by swapping one digit. 
#include <bits/stdc++.h>
using namespace std;
  
// Returns largest possible number with one
// swap such that the number is smaller than
// str. It is assumed that there are leading
// 0s.
string prevNum(string str)
{
    int len = str.length();
    int index = -1;
  
    // Traverse from right until we find 
    // a digit which is greater than its 
    // next digit. For example, in 34125,
    // our index is 4.
    for (int i = len - 2; i >= 0; i--) {
        if (str[i] > str[i+1])
        {
            index = i;
            break;
        }
    }
      
    // We can also use binary search here as
    // digits after index are sorted in increasing
    // order.
    // Find the biggest digit in the right of
    // arr[index] which is smaller than arr[index]
    int smallGreatDgt = -1;
    for (int i = len - 1; i > index; i--) {
        if (str[i] < str[index]) {
            if (smallGreatDgt == -1)
                smallGreatDgt = i;
            else if (str[i] >= str[smallGreatDgt])
                smallGreatDgt = i;
        }
    }
      
    // If index is -1 i.e. digits are 
    // in increasing order.
    if (index == -1)
        return "-1";
          
    // Swap both values
    if (smallGreatDgt != -1) 
    {
        swap(str[index], str[smallGreatDgt]);
        return str;
    }
      
    return "-1";
}
  
// Drivers code
int main()
{
    string str = "34125";
    cout << prevNum(str);
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program to find the largest smaller 
// number by swapping one digit.
class GFG 
{
  
    // Returns largest possible number  
    // with one swap such that the number  
    // is smaller than str. It is assumed  
    // that there are leading 0s. 
    static String prevNum(String str)
    {
        int len = str.length();
        int index = -1;
  
        // Traverse from right until we find 
        // a digit which is greater than its 
        // next digit. For example, in 34125, 
        // our index is 4. 
        for (int i = len - 2; i >= 0; i--) 
        {
            if (str.charAt(i) > str.charAt(i + 1)) 
            {
                index = i;
                break;
            }
        }
  
        // We can also use binary search here as 
        // digits after index are sorted in increasing 
        // order. 
        // Find the biggest digit in the right of 
        // arr[index] which is smaller than arr[index] 
        int smallGreatDgt = -1;
        for (int i = len - 1; i > index; i--)
        {
            if (str.charAt(i) < str.charAt(index)) 
            {
                if (smallGreatDgt == -1
                {
                    smallGreatDgt = i;
                
                else if (str.charAt(i) >= 
                        str.charAt(smallGreatDgt))
                {
                    smallGreatDgt = i;
                }
            }
        }
  
        // If index is -1 i.e. digits are 
        // in increasing order. 
        if (index == -1)
        {
            return "-1";
        }
  
        // Swap both values 
        if (smallGreatDgt != -1)
        {
            str = swap(str, index, smallGreatDgt);
            return str;
        }
  
        return "-1";
    }
  
    static String swap(String str, int i, int j) 
    {
        char ch[] = str.toCharArray();
        char temp = ch[i];
        ch[i] = ch[j];
        ch[j] = temp;
        return String.valueOf(ch);
    }
  
    // Driver code 
    public static void main(String[] args) 
    {
        String str = "34125";
        System.out.println(prevNum(str));
    }
  
  
// This code is contributed by 29AjayKumar

chevron_right


PHP

filter_none

edit
close

play_arrow

link
brightness_4
code

<?php
// PHP program to find the 
// largest smaller number 
// by swapping one digit. 
// Returns largest possible 
// number with one swap such 
// that the number is smaller 
// than str. It is assumed 
// that there are leading
// 0s.
  
function prevNum( $str)
{
    $len = strlen($str);
    $index = -1;
  
    // Traverse from right 
    // until we find a digit
    // which is greater than 
    // its next digit. For 
    // example, in 34125,
    // our index is 4.
    for ($i = $len - 2; $i >= 0; $i--)
    {
        if ($str[$i] > $str[$i + 1])
        {
            $index = $i;
            break;
        }
    }
      
    // We can also use binary 
    // search here as digits 
    // after index are sorted
    // in increasing order.
    // Find the biggest digit
    // in the right of arr[index]
    // which is smaller than 
    // arr[index]
    $smallGreatDgt = -1;
    for ($i = $len - 1; 
         $i > $index; $i--)
    {
        if ($str[$i] < $str[$index]) 
        {
            if ($smallGreatDgt == -1)
                $smallGreatDgt = $i;
            else if ($str[$i] >= $str[$smallGreatDgt])
                $smallGreatDgt = $i;
        }
    }
      
    // If index is -1 i.e. 
    // digits are in
    // increasing order.
    if ($index == -1)
        return "-1";
          
    // Swap both values
    if ($smallGreatDgt != -1) 
    {
        list($str[$index], 
             $str[$smallGreatDgt]) = array($str[$smallGreatDgt], 
                                           $str[$index]);
                                             
        // swap(str[index],
        // str[smallGreatDgt]);
        return $str;
    }
      
    return "-1";
}
  
// Driver code
$str = "34125";
echo prevNum($str);
      
// This code is contributed 
// by akt_mit
?>

chevron_right



Output:

32145


My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.