Largest number not exceeding N that does not contain any of the digits of S
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 |
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 contributed by divyesh072019 |
Javascript
<script> // JavaScript program to implement // the above approach // Function to obtain the largest number not exceeding // num which does not contain any digits present in S function greatestReducedNumber( num, s){ // Stores digits of S let vis_s = [ false , false , false , false , false , false , false , false , false , false ]; // Traverse the string S for (let i = 0; i < s.length; i++) { // Set occurrence as true vis_s[Number(s[i]) - 48] = true ; } let n = num.length; let inn = -1; // Traverse the string n for (let i = 0; i < n; i++) { if (vis_s[Number(num[i]) - '0' ]) { inn = i; break ; } } // All digits of num are not // present in string s if (inn == -1) { return num; } for (let dig = String(num[inn]); dig >= '0' ; dig--) { if (vis_s[Number(dig) - '0' ] == 0) { num[inn] = dig; break ; } } let LargestDig = '0' ; for (let 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 (let i = inn + 1; i < n; i++) { num[i] = LargestDig; } // Counting leading zeroes let Count = 0; for (let i = 0; i < n; i++) { if (num[i] == '0' ) Count++; else break ; } // Removing leading zeroes num = Number(num).toString(); // If the string becomes null if (num.length == 0) return "0" ; // Return the largest number return num; } // Driver Code let N = "12345" ; let S = "23" ; document.write( greatestReducedNumber(N, S)); // This code is contributed by rohitsingh07052 </script> |
11999
Time complexity: O(|N| + |s|)
Auxiliary space: O(1)