给定数字N的字符串形式。任务是找到与N具有相同数字集且小于N的最大数字。如果找不到任何这样的数字,则打印“不可能”。
例子:
Input: N = "218765"
Output: 218756
Input: N = "1234"
Output: Not Possible
Input: N = "262345"
Output: 256432
以下是关于小于N的最大数的一些观察结果:
- 如果所有数字都按升序排列,则输出始终为“不可能”。例如1234。
- 如果所有数字都按降序排列,那么我们需要交换最后两位数字。例如4321。
- 对于其他情况,我们需要从最右边处理数字(为什么?因为我们需要找到所有较小数字中的最大数字)。
算法:
- 从最右边的数字遍历给定的数字,继续遍历直到找到一个比先前遍历的数字更大的数字。例如,如果输入数字为“ 262345”,则由于在6处比前一个数字5大,所以我们在6处停止。如果找不到这样的数字,则输出为“不可能”。
- 现在,在上述找到的数字“ d”的右侧搜索小于“ d”的最大数字。对于“ 262345”,6的右侧包含“ 2345”。小于6的最大数字是5。
- 交换上面找到的两位数,在上面的示例中我们得到“ 252346”。
- 现在,按降序对从“ d”旁边的位置到数字末尾的所有数字进行排序。排序后得到的数字就是输出。对于上面的示例,我们将数字以粗体25 2346排序。我们得到256432 ,这是输入262345的先前较小的数字。 li
下面是上述方法的实现:
C++
// C++ implementation of the above approach
#include
using namespace std;
// Function to find previous number
void findPrevious(string number, int n)
{
int i, j;
// I) Start from the right most digit
// and find the first digit that is
// smaller than the digit next to it.
for (i = n - 1; i > 0; i--)
if (number[i] < number[i - 1])
break;
// If no such digit is found
// then all digits are in ascending order
// means there cannot be a smallest number
// with same set of digits
if (i == 0) {
cout << "Previous number is not possible";
return;
}
// II) Find the greatest digit on
// right side of (i-1)'th digit that is
// smaller than number[i-1]
int x = number[i - 1], greatest = i;
for (j = i; j < n; j++)
if (number[j] < x && number[j] > number[greatest])
greatest = j;
// III) Swap the above found smallest digit with number[i-1]
swap(number[greatest], number[i - 1]);
// IV) Sort the digits after (i-1) in descending order
sort(number.begin() + i, number.begin() + n, greater());
cout << "Greatest smaller number with same set of digits is " << number;
return;
}
// Driver code
int main()
{
string digits = "262345";
int n = digits.length();
findPrevious(digits, n);
return 0;
}
Java
// Java implementation of the above approach
import java.util.*;
class GFG
{
// Function to find previous number
static void findPrevious(char[] number, int n)
{
int i, j;
// I) Start from the right most digit
// and find the first digit that is
// smaller than the digit next to it.
for (i = n - 1; i > 0; i--)
{
if (number[i] < number[i - 1])
{
break;
}
}
// If no such digit is found
// then all digits are in ascending order
// means there cannot be a smallest number
// with same set of digits
if (i == 0)
{
System.out.print("Previous number is not possible");
return;
}
// II) Find the greatest digit on
// right side of (i-1)'th digit that is
// smaller than number[i-1]
int x = number[i - 1], greatest = i;
for (j = i; j < n; j++)
{
if (number[j] < x && number[j] > number[greatest])
{
greatest = j;
}
}
// III) Swap the above found smallest digit with number[i-1]
swap(number, greatest, i - 1);
// IV) Sort the digits after (i-1) in descending order
Arrays.sort(number, i, n);
reverse(number, i, n - 1);
System.out.print("Greatest smaller number with" +
"same set of digits is " + String.valueOf(number));
return;
}
static String swap(char[] ch, int i, int j)
{
char temp = ch[i];
ch[i] = ch[j];
ch[j] = temp;
return String.valueOf(ch);
}
static void reverse(char str[], int start, int end)
{
// Temporary variable to store character
char temp;
while (start <= end)
{
// Swapping the first and last character
temp = str[start];
str[start] = str[end];
str[end] = temp;
start++;
end--;
}
}
// Driver code
public static void main(String[] args)
{
String digits = "262345";
int n = digits.length();
findPrevious(digits.toCharArray(), n);
}
}
// This code has been contributed by 29AjayKumar
Python3
# Python3 implementation of the above approach
# Function to find previous number
def findPrevious(number, n):
# This is necessary as strings
# do not support item assignment
number = list(number)
i, j = -1, -1
# I) Start from the right most digit
# and find the first digit that is
# smaller than the digit next to it.
for i in range(n - 1, 0, -1):
if number[i] < number[i - 1]:
break
# If no such digit is found
# then all digits are in ascending order
# means there cannot be a smallest number
# with same set of digits
if i == 0:
print("Previous number is not possible")
return
x, greatest = number[i - 1], i
# II) Find the greatest digit on
# right side of(i-1)'th digit that is
# smaller than number[i-1]
for j in range(i, n):
if (number[j] < x and
number[j] > number[greatest]):
greatest = j
# III) Swap the above found smallest digit
# with number[i-1]
(number[greatest],
number[i - 1]) = (number[i - 1],
number[greatest])
l = number[i:]
del number[i:]
# IV) Sort the digits after(i-1)
# in descending order
l.sort(reverse = True)
number += l
# Again join the list to make it string
number = '' . join(number)
print("Greatest smaller number with",
"same set of digits is", number)
return
# Driver Code
if __name__ == "__main__":
digits = "262345"
n = len(digits)
findPrevious(digits, n)
# This code is contributed by sanjeev2552
C#
// c# implementation of the approach
using System;
using System.Collections.Generic;
class GFG
{
// Function to find previous number
static void findPrevious(char[] number, int n)
{
int i, j;
// I) Start from the right most digit
// and find the first digit that is
// smaller than the digit next to it.
for (i = n - 1; i > 0; i--)
{
if (number[i] < number[i - 1])
{
break;
}
}
// If no such digit is found
// then all digits are in ascending order
// means there cannot be a smallest number
// with same set of digits
if (i == 0)
{
Console.Write("Previous number is not possible");
return;
}
// II) Find the greatest digit on
// right side of (i-1)'th digit that is
// smaller than number[i-1]
int x = number[i - 1], greatest = i;
for (j = i; j < n; j++)
{
if (number[j] < x && number[j] > number[greatest])
{
greatest = j;
}
}
// III) Swap the above found
// smallest digit with number[i-1]
swap(number, greatest, i - 1);
// IV) Sort the digits after (i-1) in descending order
Array.Sort(number, i, n-i);
reverse(number, i, n - 1);
Console.Write("Greatest smaller number with" +
"same set of digits is " + String.Join("",number));
return;
}
static String swap(char[] ch, int i, int j)
{
char temp = ch[i];
ch[i] = ch[j];
ch[j] = temp;
return String.Join("",ch);
}
static void reverse(char []str, int start, int end)
{
// Temporary variable to store character
char temp;
while (start <= end)
{
// Swapping the first and last character
temp = str[start];
str[start] = str[end];
str[end] = temp;
start++;
end--;
}
}
// Driver code
public static void Main(String[] args)
{
String digits = "262345";
int n = digits.Length;
findPrevious(digits.ToCharArray(), n);
}
}
/* This code contributed by PrinciRaj1992 */
输出:
Greatest smaller number with same set of digits is 256432