给定一个数字字符串N ( 1 ≤ |N| ≤ 10 5 ) 和另一个数字字符串S ( 1 ≤ |S| ≤ 10 5 ),任务是找到最大数 ≤ N使得它不包含数字字符串S 。如果需要,删除前导零。
注意:字符串S不包含‘0’ 。
例子:
Input: N = “2004”, S = “2”
Output: 1999
Explanation:
2004 has digit 2 which is in the string S.
Therefore, keep reducing it by 1 until the number obtained does not contain 2.
Therefore, the largest number that can be obtained is 1999.
Input: N = “12345”, S = “23”
Output: 11999
朴素方法:对于N 的每个值,检查它是否包含S 的任何数字。继续将N减1,直到S中出现的任何数字都不会出现在N 中。
时间复杂度: O(|N| * log(|N|) * |S|)
辅助空间: O(1)
高效的方法:可以使用哈希优化上述方法。请按照以下步骤解决问题:
- 遍历字符串S的字符和S的不同字符存储在一个地图。
- 遍历字符串N 。
- 如果发现N 的任何数字存在于S 中,比如第idx个数字,将N[idx]减少到S 中不存在的最大数字,比如LargestDig 。
- [idx + 1, |N|范围内的数字– 1]更改为LargestDig 。
Illustration:
Consider N = “2004” and S = “2”.
To remove 2, it is changed to 1 and the remaining digits are changed to the largest digit which is not present in S, that is digit 9.
- 从数字中删除所有前导零。
下面是上述方法的实现。
C++
// C++ program to implement
// the above approach
#include
using namespace std;
// Function to obtain the largest number not exceeding
// num which does not contain any digits present in S
string greatestReducedNumber(string num, string s)
{
// Stores digits of S
vector vis_s(10, false);
// Traverse the string S
for (int i = 0; i < (int)s.size(); i++) {
// Set occurrence as true
vis_s[int(s[i]) - 48] = true;
}
int n = num.size();
int in = -1;
// Traverse the string n
for (int i = 0; i < n; i++) {
if (vis_s[(int)num[i] - '0']) {
in = i;
break;
}
}
// All digits of num are not
// present in string s
if (in == -1) {
return num;
}
for (char dig = num[in]; dig >= '0'; dig--) {
if (vis_s[(int)dig - '0'] == 0) {
num[in] = dig;
break;
}
}
char LargestDig = '0';
for (char dig = '9'; dig >= '0'; dig--) {
if (vis_s[dig - '0'] == false) {
// Largest Digit not present
// in the string s
LargestDig = dig;
break;
}
}
// Set all digits from positions
// in + 1 to n - 1 as LargestDig
for (int i = in + 1; i < n; i++) {
num[i] = LargestDig;
}
// Counting leading zeroes
int Count = 0;
for (int i = 0; i < n; i++) {
if (num[i] == '0')
Count++;
else
break;
}
// Removing leading zeroes
num.erase(0, Count);
// If the string becomes null
if ((int)num.size() == 0)
return "0";
// Return the largest number
return num;
}
// Driver Code
int main()
{
string N = "12345";
string S = "23";
cout << greatestReducedNumber(N, S);
return 0;
}
Java
// Java program to implement
// the above approach
import java.io.*;
import java.util.Arrays;
class GFG {
// Function to obtain the largest number not exceeding
// num which does not contain any digits present in S
static String greatestReducedNumber(String num,
String s)
{
// Stores digits of S
Boolean[] vis_s = new Boolean[10];
Arrays.fill(vis_s, Boolean.FALSE);
// Traverse the string S
for (int i = 0; i < (int)s.length(); i++) {
// Set occurrence as true
vis_s[(int)(s.charAt(i)) - 48] = true;
}
int n = num.length();
int in = -1;
// Traverse the string n
for (int i = 0; i < n; i++) {
if (vis_s[(int)num.charAt(i) - '0']) {
in = i;
break;
}
}
// All digits of num are not
// present in string s
if (in == -1) {
return num;
}
for (char dig = num.charAt(in); dig >= '0'; dig--) {
if (vis_s[(int)dig - '0'] == false) {
num = num.substring(0, in) + dig
+ num.substring(in + 1, n);
break;
}
}
char LargestDig = '0';
for (char dig = '9'; dig >= '0'; dig--) {
if (vis_s[dig - '0'] == false) {
// Largest Digit not present
// in the string s
LargestDig = dig;
break;
}
}
// Set all digits from positions
// in + 1 to n - 1 as LargestDig
for (int i = in + 1; i < n; i++) {
num = num.substring(0, i) + LargestDig;
}
// Counting leading zeroes
int Count = 0;
for (int i = 0; i < n; i++) {
if (num.charAt(i) == '0')
Count++;
else
break;
}
// Removing leading zeroes
num = num.substring(Count, n);
// If the string becomes null
if ((int)num.length() == 0)
return "0";
// Return the largest number
return num;
}
// Driver Code
public static void main(String[] args)
{
String N = "12345";
String S = "23";
System.out.print(greatestReducedNumber(N, S));
}
}
// This code is contributed by subhammahato348
Python3
# Python3 program to implement
# the above approach
# Function to obtain the largest number not exceeding
# num which does not contain any digits present in S
def greatestReducedNumber(num, s) :
# Stores digits of S
vis_s = [False] * 10
# Traverse the string S
for i in range(len(s)) :
# Set occurrence as true
vis_s[(ord)(s[i]) - 48] = True
n = len(num)
In = -1
# Traverse the string n
for i in range(n) :
if (vis_s[ord(num[i]) - ord('0')]) :
In = i
break
# All digits of num are not
# present in string s
if (In == -1) :
return num
for dig in range(ord(num[In]), ord('0') - 1, -1) :
if (vis_s[dig - ord('0')] == False) :
num = num[0 : In] + chr(dig) + num[In + 1 : n - In - 1]
break
LargestDig = '0'
for dig in range(ord('9'), ord('0') - 1, -1) :
if (vis_s[dig - ord('0')] == False) :
# Largest Digit not present
# in the string s
LargestDig = dig
break
# Set all digits from positions
# in + 1 to n - 1 as LargestDig
for i in range(In + 1, n) :
num = num[0 : i] + chr(LargestDig)
# Counting leading zeroes
Count = 0
for i in range(n) :
if (num[i] == '0') :
Count += 1
else :
break
# Removing leading zeroes
num = num[Count : n]
# If the string becomes null
if (int(len(num)) == 0) :
return "0"
# Return the largest number
return num
# Driver code
N = "12345"
S = "23"
print(greatestReducedNumber(N, S))
# This code is contributed by divyeshrabadiya07.
C#
// C# program to implement
// the above approach
using System;
using System.Collections.Generic;
class GFG
{
// Function to obtain the largest number not exceeding
// num which does not contain any digits present in S
static string greatestReducedNumber(string num, string s)
{
// Stores digits of S
bool[] vis_s = new bool[10];
// Traverse the string S
for (int i = 0; i < (int)s.Length; i++) {
// Set occurrence as true
vis_s[(int)(s[i]) - 48] = true;
}
int n = num.Length;
int In = -1;
// Traverse the string n
for (int i = 0; i < n; i++) {
if (vis_s[(int)num[i] - '0']) {
In = i;
break;
}
}
// All digits of num are not
// present in string s
if (In == -1) {
return num;
}
for (char dig = num[In]; dig >= '0'; dig--) {
if (vis_s[(int)dig - '0'] == false) {
num = num.Substring(0, In) + dig + num.Substring(In + 1, n - In - 1);
break;
}
}
char LargestDig = '0';
for (char dig = '9'; dig >= '0'; dig--) {
if (vis_s[dig - '0'] == false) {
// Largest Digit not present
// in the string s
LargestDig = dig;
break;
}
}
// Set all digits from positions
// in + 1 to n - 1 as LargestDig
for (int i = In + 1; i < n; i++) {
num = num.Substring(0, i) + LargestDig;
}
// Counting leading zeroes
int Count = 0;
for (int i = 0; i < n; i++) {
if (num[i] == '0')
Count++;
else
break;
}
// Removing leading zeroes
num = num.Substring(Count, n);
// If the string becomes null
if ((int)num.Length == 0)
return "0";
// Return the largest number
return num;
}
// Driver code
static void Main() {
string N = "12345";
string S = "23";
Console.Write(greatestReducedNumber(N, S));
}
}
// This code is contibuted by divyesh072019
Javascript
11999
时间复杂度: O(|N| + |s|)
辅助空间: O(1)