给定一个非负数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(其中n是num中的位数),然后找到第一个具有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是数字的总数。