📌  相关文章
📜  使用最多一次交换操作形成最小的数字

📅  最后修改于: 2021-05-04 11:37:05             🧑  作者: Mango

给定一个非负数num 。问题是最多对数字num进行一次交换操作,以使结果为最小的可能数字。该数字可能非常大,因此可以使用字符串类型来存储数字。输入不包含前导0,输出也不应包含前导0。
注意:结果数字中应与原始数字中存在相同的一组数字。

例子:

Input : n = 9625635
Output : 2695635
Swapped the digits 9 and 2.

Input : n = 1205763
Output : 1025763

方法:
创建一个数组rightMin []rightMin [i]包含最小数字的索引,该数字位于num [i]的右侧,并且小于num [i] 。如果不存在这样的数字,则rightMin [i] = -1。现在,检查num [0]是否具有不小于0的右小数。如果是,则将第一个数字与其右小数互换。否则,将rightMin []数组从i = 1遍历到n-1(其中nnum中的位数),然后找到第一个具有rightMin [i] = -1的元素。执行swap(num [i],num [rightMin [i]])操作并中断。

C++
// C++ implementation to form the smallest
// number using at most one swap operation
#include 
using namespace std;
  
// function to form the smallest number
// using at most one swap operation
string smallestNumber(string num)
{
    int n = num.size();
    int rightMin[n], right;
  
    // for the rightmost digit, there
    // will be no smaller right digit
    rightMin[n - 1] = -1;
  
    // index of the smallest right digit
    // till the current index from the
    // right direction
    right = n - 1;
  
    // traverse the array from second
    // right element up to the left
    // element
    for (int i = n - 2; i >= 1; i--) {
        // if 'num[i]' is greater than
        // the smallest digit encountered
        // so far
        if (num[i] >= num[right])
            rightMin[i] = right;
  
        else {
            // for cases like 120000654 or 1000000321
            // rightMin will be same for all 0's
            // except the first from last
            if (num[i] == num[i + 1]) {
                rightMin[i] = right;
            }
            else {
                rightMin[i] = -1;
                right = i;
            }
        }
    }
  
    // special condition for the 1st digit so that
    // it is not swapped with digit '0'
    int small = -1;
    for (int i = 1; i < n; i++)
        if (num[i] != '0') {
            if (small == -1) {
                if (num[i] < num[0])
                    small = i;
            }
            else if (num[i] <= num[small])
                small = i;
        }
  
    if (small != -1)
        swap(num[0], num[small]);
  
    else {
        // traverse the 'rightMin[]' array from
        // 2nd digit up to the last digit
        for (int i = 1; i < n; i++) {
            // if for the current digit, smaller
            // right digit exists, then swap it
            // with its smaller right digit and
            // break
            if (rightMin[i] != -1 && num[i] != num[rightMin[i]]) {
                // performing the required
                // swap operation
                swap(num[i], num[rightMin[i]]);
                break;
            }
        }
    }
  
    // required smallest number
    return num;
}
  
// Driver program to test above
int main()
{
    string num = "9625635";
    cout << "Smallest number: "
         << smallestNumber(num);
    return 0;
}


Java
// Java implementation to form the smallest
// number using at most one swap operation
import java.util.*;
import java.lang.*;
  
public class GeeksforGeeks {
  
    // function to form the smallest number
    // using at most one swap operation
    public static String smallestNumber(String str)
    {
  
        char[] num = str.toCharArray();
        int n = str.length();
        int[] rightMin = new int[n];
  
        // for the rightmost digit, there
        // will be no smaller right digit
        rightMin[n - 1] = -1;
  
        // index of the smallest right digit
        // till the current index from the
        // right direction
        int right = n - 1;
  
        // traverse the array from second
        // right element up to the left
        // element
        for (int i = n - 2; i >= 1; i--) {
            // if 'num[i]' is greater than
            // the smallest digit
            // encountered so far
            if (num[i] > num[right])
                rightMin[i] = right;
  
            else {
                // there is no smaller right
                // digit for 'num[i]'
                rightMin[i] = -1;
  
                // update 'right' index
                right = i;
            }
        }
  
        // special condition for the 1st
        // digit so that it is not swapped
        // with digit '0'
        int small = -1;
        for (int i = 1; i < n; i++)
            if (num[i] != '0') {
                if (small == -1) {
                    if (num[i] < num[0])
                        small = i;
                }
                else if (num[i] < num[small])
                    small = i;
            }
  
        if (small != -1) {
            char temp;
            temp = num[0];
            num[0] = num[small];
            num[small] = temp;
        }
        else {
            // traverse the 'rightMin[]'
            // array from 2nd digit up
            // to the last digit
            for (int i = 1; i < n; i++) {
                // if for the current digit,
                // smaller right digit exists,
                // then swap it with its smaller
                // right digit and break
                if (rightMin[i] != -1) {
                    // performing the required
                    // swap operation
                    char temp;
                    temp = num[i];
                    num[i] = num[rightMin[i]];
                    num[rightMin[i]] = temp;
                    break;
                }
            }
        }
  
        // required smallest number
        return (new String(num));
    }
  
    // driver function
    public static void main(String argc[])
    {
        String num = "9625635";
        System.out.println("Smallest number: " + smallestNumber(num));
    }
}
  
/*This code is contributed by Sagar Shukla.*/


Python 3
# Python implementation to form the smallest
# number using at most one swap operation
  
# function to form the smallest number
# using at most one swap operation
def smallestNumber(num):
    num = list(num)
    n = len(num)
    rightMin = [0]*n
    right = 0
  
    # for the rightmost digit, there
    # will be no smaller right digit
    rightMin[n-1] = -1;
      
    # index of the smallest right digit
    # till the current index from the
    # right direction
    right = n-1;
  
    # traverse the array from second
    # right element up to the left
    # element
    for i in range(n-2, 0, -1):
  
        # if 'num[i]' is greater than
        # the smallest digit encountered
        # so far
        if num[i] > num[right]:
            rightMin[i] = right
          
        else:
  
            # there is no smaller right
            # digit for 'num[i]'
            rightMin[i] = -1
  
            # update 'right' index
            right = i
      
    # special condition for the 1st digit so that
    # it is not swapped with digit '0'
    small = -1
    for i in range(1, n):
  
        if num[i] != '0':
              
            if small == -1:
                  
                if num[i] < num[0]:
                    small = i
              
            elif num[i] < num[small]:
                small = i
          
    if small != -1:
        num[0], num[small] = num[small], num[0]
    else:
  
        # traverse the 'rightMin[]' array from 
        # 2nd digit up to the last digit
        for i in range(1, n):
  
            # if for the current digit, smaller
            # right digit exists, then swap it
            # with its smaller right digit and
            # break
            if rightMin[i] != -1:
  
                # performing the required
                # swap operation
                num[i], num[rightMin[i]] = num[rightMin[i]], num[i]
                break
      
    # required smallest number
    return ''.join(num)
  
# Driver Code
if __name__ == "__main__":
    num = "9625635"
    print("Smallest number: ", smallestNumber(num))
  
# This code is contributed by 
# sanjeev2552


C#
// C# implementation to form the smallest
// number using at most one swap operation.
using System;
  
public class GeeksforGeeks {
  
    // function to form the smallest number
    // using at most one swap operation
    public static String smallestNumber(String str)
    {
  
        char[] num = str.ToCharArray();
        int n = str.Length;
        int[] rightMin = new int[n];
  
        // for the rightmost digit, there
        // will be no smaller right digit
        rightMin[n - 1] = -1;
  
        // index of the smallest right digit
        // till the current index from the
        // right direction
        int right = n - 1;
  
        // traverse the array from second
        // right element up to the left
        // element
        for (int i = n - 2; i >= 1; i--) {
  
            // if 'num[i]' is greater than
            // the smallest digit
            // encountered so far
            if (num[i] > num[right])
                rightMin[i] = right;
  
            else {
  
                // there is no smaller right
                // digit for 'num[i]'
                rightMin[i] = -1;
  
                // update 'right' index
                right = i;
            }
        }
  
        // special condition for the 1st
        // digit so that it is not swapped
        // with digit '0'
        int small = -1;
        for (int i = 1; i < n; i++)
            if (num[i] != '0') {
                if (small == -1) {
                    if (num[i] < num[0])
                        small = i;
                }
                else if (num[i] < num[small])
                    small = i;
            }
  
        if (small != -1) {
            char temp;
            temp = num[0];
            num[0] = num[small];
            num[small] = temp;
        }
        else {
  
            // traverse the 'rightMin[]'
            // array from 2nd digit up
            // to the last digit
            for (int i = 1; i < n; i++) {
  
                // if for the current digit,
                // smaller right digit exists,
                // then swap it with its smaller
                // right digit and break
                if (rightMin[i] != -1) {
                    // performing the required
                    // swap operation
                    char temp;
                    temp = num[i];
                    num[i] = num[rightMin[i]];
                    num[rightMin[i]] = temp;
                    break;
                }
            }
        }
  
        // required smallest number
        return (new String(num));
    }
  
    // Driver code
    public static void Main()
    {
        String num = "9625635";
        Console.Write("Smallest number: " + smallestNumber(num));
    }
}
  
// This code is contributed by Nitin Mittal.


PHP
= 1; $i--) 
    { 
        // if 'num[i]' is greater 
        // than the smallest digit  
        // encountered so far
        if ($num[$i] > $num[$right])
            $rightMin[$i] = $right;
  
        else
        { 
            // there is no smaller 
            // right digit for 'num[i]'
            $rightMin[$i] = -1;
  
            // update 'right' index
            $right = $i;
        }
    }
  
    // special condition for 
    // the 1st digit so that
    // it is not swapped with
    // digit '0'
    $small = -1;
    for ($i = 1; $i < $n; $i++)
        if ($num[$i] != '0')
        {
            if ($small == -1)
            {
                if ($num[$i] < $num[0])
                    $small = $i;
            }
            else if ($num[$i] < $num[$small])
                $small = $i;                 
        }
      
    if ($small != -1)
    {
        $tmp = $num[0];
        $num[0] = $num[$small];
        $num[$small] = $tmp;
    }
    else
    {
        // traverse the 'rightMin[]' 
        // array from 2nd digit up 
        // to the last digit
        for ($i = 1; $i < $n; $i++) 
        { 
            // if for the current 
            // digit, smaller right 
            // digit exists, then 
            // swap it with its 
            // smaller right digit 
            // and break
            if ($rightMin[$i] != -1) 
            { 
                // performing the required 
                // swap operation
                $tmp = $num[$i];
                $num[$i] = $num[$rightMin[$i]];
                $num[$rightMin[$i]] = $tmp;
                break;
            }
        }
    }
  
    // required smallest number
    return $num;
}
  
// Driver Code
$num = "9625635";
echo "Smallest number: " . 
     smallestNumber($num);
  
// This code is contributed by mits
?>


输出:

Smallest number: 2695635

时间复杂度: O(n),其中n是位数。
辅助空间: O(n),其中n是数字的总数。