Given a numberic string N (1 ≤ |N| ≤ 105) and another numeric string S (1 ≤ |S| ≤ 105), the task is to find the maximum number ≤ N such that it doesn’t contain digits of string S. Remove leading zeros, if required.
Note: The string S doesn’t contain ‘0’.
Examples:
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
Naive Approach: For every value of N, check if it contains any of the digits of S. Keep reducing N by 1 until any digit that is present in S does not occur in N.
Time Complexity: O(|N| * log(|N|) * |S|)
Auxiliary Space: O(1)
Efficient Approach: The above approach can be optimized using Hashing. Follow the steps below to solve the problem:
- Iterate over the characters of the string S and store the distinct characters of S in a Map.
- Traverse the string N.
- If any digit of N is found to be present in S, say idxth digit, reduce N[idx] to the largest digit not present in S, say LargestDig.
- Digits in range [idx + 1, |N| – 1] are changed to 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.
- Remove all the leading zeros from the number.
Below is the implementation of the above approach.
C++
// C++ program to implement // the above approach #include <bits/stdc++.h> 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< bool > 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 |
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 |
11999
Time complexity: O(|N| + |s|)
Auxiliary space: O(1)
Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.