Given integers, N, L, and R, the task is to find the number of integers in the range L to R that does not contain the digit N. print the answer modulo 109 + 7. ( L ? R ? 101000000)
Examples:
Input: N = 5, L = 1, R = 10
Output: 9
Explanation: excluding all 5 others from 1 to 10 will be included in the answer.Input: N = 5, L = 1, R = 100
Output: 81
Explanation: Excluding 5, 15, 25, 35, 45, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 65, 75, 85, and 95 all numbers from 1 to 100 will be included in the answer
Naive approach: The basic way to solve the problem is as follows:
The basic way to solve this problem is to generate all possible combinations by using a recursive approach.
Time Complexity: O(18N), Where N is the number of digits to be filled.
Auxiliary Space: O(1)
Efficient Approach: Â The above approach can be optimized based on the following idea:
Dynamic programming can be used to solve this problem
- dp[i][j] represents numbers in the range with i digits and j represents tight condition.
- It can be observed that the recursive function is called exponential times. That means that some states are called repeatedly.Â
- So the idea is to store the value of each state. This can be done using by store the value of a state and whenever the function is called, return the stored value without computing again.
- First answer will be calculated for 0 to A – 1 and then calculated for 0 to B then latter one is subtracted with prior one to get answer for range [L, R]
Follow the steps below to solve the problem:
- Create a recursive function that takes two parameters i representing the position to be filled and j representing the tight condition.
- Call the recursive function for choosing all digits from 0 to 9 apart from N.
- Base case if size digit formed return 1;
- Create a 2d array dp[N][2] initially filled with -1.
- If the answer for a particular state is computed then save it in dp[i][j].
- If the answer for a particular state is already computed then just return dp[i][j].
Below is the implementation of the above approach:
C++
// C++ code to implement the approach #include <bits/stdc++.h> using namespace std; Â
const int MOD = 1e9 + 7; Â
// dp table initialized with -1 int dp[100001][2]; Â
// Recursive Function to find numbers // in the range L to R such that they // do not contain digit N int recur( int i, int j, int N, string& a) {     // Base case     if (i == a.size()) {         return 1;     } Â
    // If answer for current state is already     // calculated then just return dp[i][j]     if (dp[i][j] != -1)         return dp[i][j]; Â
    // Answer initialized with zero     int ans = 0; Â
    // Tight condition true     if (j == 1) { Â
        // Iterating from 0 to max value         // of tight condition           cout<<(( int )a[i] - 48)<<endl;         for ( int k = 0; k <= (( int )a[i] - 48); k++) { Â
            // N is not allowed to use             if (k == N)                 continue ; Â
            // When k is at max tight condition             // remains even in next state             if (k == (( int )a[i] - 48)) Â
                // Calling recursive function                 // for tight digit                 ans += recur(i + 1, 1, N, a); Â
            // Tight condition drops             else                 // Calling recursive function                 // for digits less than tight                 // condition digit                 ans += recur(i + 1, 0, N, a);         }     } Â
    // Tight condition false     else { Â
        // Iterating for all digits         for ( int k = 0; k <= 9; k++) { Â
            // Digit N is not possible             if (k == N)                 continue ; Â
            // Calling recursive function for             // all digits from 0 to 9             ans += recur(i + 1, 0, N, a);         }     } Â
    // Save and return dp value     return dp[i][j] = ans; } Â
// Function to find numbers // in the range L to R such that they // do not contain digit N int countInRange( int N, int A, int B) { Â
    // Initializing dp array with - 1     memset (dp, -1, sizeof (dp)); Â
    A--;     string L = to_string(A), R = to_string(B); Â
    // Numbers with sum of digits T from     // 1 to L - 1     int ans1 = recur(0, 1, N, L); Â
    // Initializing dp array with - 1     memset (dp, -1, sizeof (dp)); Â
    // Numbers with sum of digits T in the     // range 1 to R     int ans2 = recur(0, 1, N, R); Â
    // Difference of ans2 and ans1     // will generate answer for required     // range     return ans2 - ans1; } Â
// Driver Code int main() { Â Â Â Â // Input 1 Â Â Â Â int N = 5, L = 1, R = 10; Â
    // Function Call     cout << countInRange(N, L, R) << endl; Â
    // Input 2     //int N1 = 5, L1 = 1, R1 = 100; Â
    // Function Call     //cout << countInRange(N1, L1, R1) << endl;     return 0; } |
Java
// Java code to implement the approach Â
import java.io.*; import java.util.*; Â
class GFG { Â
    static final int MOD = 1_000_000_007; Â
    // dp table initialized with -1     static int [][] dp = new int [ 100001 ][ 2 ]; Â
    // Recursive Function to find numbers     // in the range L to R such that they     // do not contain digit N     static int recur( int i, int j, int N, String a)     {         // Base case         if (i == a.length()) {             return 1 ;         } Â
        // If answer for current state is already         // calculated then just return dp[i][j]         if (dp[i][j] != - 1 )             return dp[i][j]; Â
        // Answer initialized with zero         int ans = 0 ; Â
        // Tight condition true         if (j == 1 ) {             // Iterating from 0 to max value             // of tight condition             for ( int k = 0 ; k <= a.charAt(i) - '0' ; k++) {                 // N is not allowed to use                 if (k == N)                     continue ;                 // When k is at max tight condition                 // remains even in next state                 if (k == a.charAt(i) - '0' )                     // Calling recursive function                     // for tight digit                     ans += recur(i + 1 , 1 , N, a);                 // Tight condition drops                 else                     ans += recur(i + 1 , 0 , N, a);             }         }         // Tight condition false         else {             // Iterating for all digits             for ( int k = 0 ; k <= 9 ; k++) {                 // Digit N is not possible                 if (k == N)                     continue ;                 // Calling recursive function for                 // all digits from 0 to 9                 ans += recur(i + 1 , 0 , N, a);             }         } Â
        // Save and return dp value         return dp[i][j] = ans;     } Â
    // Function to find numbers     // in the range L to R such that they     // do not contain digit N     static int countInRange( int N, int A, int B)     {         // Initializing dp array with - 1         for ( int [] row : dp) {             Arrays.fill(row, - 1 );         } Â
        A--;         String L = Integer.toString(A);         String R = Integer.toString(B); Â
        // Numbers with sum of digits T from         // 1 to L - 1         int ans1 = recur( 0 , 1 , N, L); Â
        // Initializing dp array with - 1         for ( int [] row : dp) {             Arrays.fill(row, - 1 );         } Â
        // Numbers with sum of digits T in the         // range 1 to R         int ans2 = recur( 0 , 1 , N, R); Â
        // Difference of ans2 and ans1         // will generate answer for required         // range         return ans2 - ans1;     } Â
    public static void main(String[] args)     {         // Input 1         int N = 5 ;         int L = 1 ;         int R = 10 ; Â
        // Function Call         System.out.println(countInRange(N, L, R)); Â
        // Input 2         int N1 = 5 ;         int L1 = 1 ;         int R1 = 100 ; Â
        // Function Call         System.out.println(countInRange(N1, L1, R1));     } } Â
// This contributed by lokeshmvs21. |
Python3
# Python code to implement the approach MOD = 1e9 + 7 ; Â
# dp table initialized with -1 dp = [[ - 1 ] * ( 2 ) for _ in range ( 100001 )]; Â
# Recursive Function to find numbers # in the range L to R such that they # do not contain digit N def recur(i, j, N, a):     # Base case     if (i = = len (a)) :         return 1 ;          # If answer for current state is already     # calculated then just return dp[i][j]     if (dp[i][j] ! = - 1 ):         return dp[i][j]; Â
    # Answer initialized with zero     ans = 0 ; Â
    # Tight condition true     if (j = = 1 ) : Â
        # Iterating from 0 to max value         # of tight condition         for k in range ( 0 , int (a[i]) + 1 ): Â
            # N is not allowed to use             if (k = = N):                 continue ; Â
            # When k is at max tight condition             # remains even in next state             if (k = = int (a[i])): Â
                # Calling recursive function                 # for tight digit                 ans + = recur(i + 1 , 1 , N, a); Â
            # Tight condition drops             else :                 # Calling recursive function                 # for digits less than tight                 # condition digit                 ans + = recur(i + 1 , 0 , N, a);          Â
    # Tight condition false     else :         # Iterating for all digits         for k in range ( 0 , 10 ): Â
            # Digit N is not possible             if (k = = N):                 continue ; Â
            # Calling recursive function for             # all digits from 0 to 9             ans + = recur(i + 1 , 0 , N, a);          Â
    # Save and return dp value     dp[i][j] = ans;     return dp[i][j]; Â
# Function to find numbers # in the range L to R such that they # do not contain digit N def countInRange( N, A, B):     # Initializing dp array with - 1     for i in range ( 0 , 100001 ):         for j in range ( 0 , 2 ):             dp[i][j] = - 1 ;          A - = 1 ;     L = str (A);     R = str (B); Â
    # Numbers with sum of digits T from     # 1 to L - 1     ans1 = recur( 0 , 1 , N, L); Â
    # Initializing dp array with - 1     for i in range ( 0 , 100001 ):         for j in range ( 0 , 2 ):             dp[i][j] = - 1 ;     # Numbers with sum of digits T in the     # range 1 to R     ans2 = recur( 0 , 1 , N, R); Â
    # Difference of ans2 and ans1     # will generate answer for required     # range     return ans2 - ans1; Â
# Driver Code # Input 1 N = 5 ; L = 1 ; R = 10 ; Â
# Function Call print (countInRange(N, L, R)); Â
# Input 2 N1 = 5 ; L1 = 1 ; R1 = 100 ; Â
# Function Call print (countInRange(N1, L1, R1)); Â
# This code is contributed by agrawalpooja976. |
C#
using System; Â
namespace GFG {   static class Program   {     static readonly int MOD = 1_000_000_007; Â
    // dp table initialized with -1     static int [,] dp = new int [100001, 2]; Â
    // Recursive Function to find numbers     // in the range L to R such that they     // do not contain digit N     static int Recur( int i, int j, int N, string a)     {       // Base case       if (i == a.Length)       {         return 1;       } Â
      // If answer for current state is already       // calculated then just return dp[i][j]       if (dp[i, j] != -1)         return dp[i, j]; Â
      // Answer initialized with zero       int ans = 0; Â
      // Tight condition true       if (j == 1)       {         // Iterating from 0 to max value         // of tight condition         for ( int k = 0; k <= a[i] - '0' ; k++)         {           // N is not allowed to use           if (k == N)             continue ; Â
          // When k is at max tight condition           // remains even in next state           if (k == a[i] - '0' )             // Calling recursive function             // for tight digit             ans += Recur(i + 1, 1, N, a);           // Tight condition drops           else             ans += Recur(i + 1, 0, N, a);         }       }       // Tight condition false       else       {         // Iterating for all digits         for ( int k = 0; k <= 9; k++)         {           // Digit N is not possible           if (k == N)             continue ;           // Calling recursive function for           // all digits from 0 to 9           ans += Recur(i + 1, 0, N, a);         }       } Â
      // Save and return dp value       return dp[i, j] = ans;     } Â
    // Function to find numbers     // in the range L to R such that they     // do not contain digit N     static int CountInRange( int N, int A, int B)     {       // Initializing dp array with - 1       for ( int i = 0; i < dp.GetLength(0); i++)       {         for ( int j = 0; j < dp.GetLength(1); j++)         {           dp[i, j] = -1;         }       } Â
      A--;       string L = A.ToString();       string R = B.ToString(); Â
      // Numbers with sum of digits T from       // 1 to L - 1       int ans1 = Recur(0, 1, N, L); Â
      // Initializing dp array with - 1       for ( int i = 0; i < dp.GetLength(0); i++)       {         for ( int j = 0; j < dp.GetLength(1); j++)         {           dp[i, j] = -1;         }       } Â
      // Numbers with sum of digits T in the       // range 1 to R       int ans2 = Recur(0, 1, N, R); Â
      // Difference of ans2 and ans1       // will generate answer for required       // range       return ans2 - ans1;     } Â
    // Main Method     static void Main( string [] args)     {       // Input 1       int N = 5;       int L = 1;       int R = 10; Â
      // Function Call       Console.WriteLine(CountInRange(N, L, R)); Â
      // Input 2       int N1 = 5;       int L1 = 1;       int R1 = 100; Â
      // Function Call       Console.WriteLine(CountInRange(N1, L1, R1));     }   } } Â
// This code is contributed by surajrasr7277 |
Javascript
// Javascript code to implement the approach Â
let MOD = 1e9 + 7; Â
// dp table initialized with -1 let dp = new Array(100001); for (let i=0; i<100001; i++) Â Â Â Â dp[i]= new Array(2); Â
Â
// Recursive Function to find numbers // in the range L to R such that they // do not contain digit N function recur(i, j, N, a) {     // Base case     if (i == a.length) {         return 1;     } Â
    // If answer for current state is already     // calculated then just return dp[i][j]     if (dp[i][j] != -1)         return dp[i][j]; Â
    // Answer initialized with zero     let ans = 0; Â
    // Tight condition true     if (j == 1) { Â
        // Iterating from 0 to max value         // of tight condition         for (let k = 0; k <= (parseInt(a[i])); k++) { Â
            // N is not allowed to use             if (k == N)                 continue ; Â
            // When k is at max tight condition             // remains even in next state             if (k == (parseInt(a[i]))) Â
                // Calling recursive function                 // for tight digit                 ans = ans + recur(i + 1, 1, N, a);                              // Tight condition drops             else                 // Calling recursive function                 // for digits less than tight                 // condition digit                  ans = ans + recur(i + 1, 0, N, a);         }     } Â
    // Tight condition false     else { Â
        // Iterating for all digits         for (let k = 0; k <= 9; k++) { Â
            // Digit N is not possible             if (k == N)                 continue ; Â
            // Calling recursive function for             // all digits from 0 to 9             ans += recur(i + 1, 0, N, a);         }     } Â
    // Save and return dp value     return dp[i][j] = ans; } Â
// Function to find numbers // in the range L to R such that they // do not contain digit N function countInRange(N, A, B) { Â
    // Initializing dp array with - 1     for (let i=0; i<100001; i++)         for (let j=0; j<2; j++)             dp[i][j]=-1;     A--;     let L = A.toString(), R = B.toString(); Â
    // Numbers with sum of digits T from     // 1 to L - 1     let ans1 = recur(0, 1, N, L); Â
    // Initializing dp array with - 1     for (let i=0; i<100001; i++)         for (let j=0; j<2; j++)             dp[i][j]=-1;     // Numbers with sum of digits T in the     // range 1 to R     let ans2 = recur(0, 1, N, R); Â
    // Difference of ans2 and ans1     // will generate answer for required     // range     return ans2 - ans1; } Â
// Driver Code     // Input 1     let N = 5, L = 1, R = 10; Â
    // Function Call     document.write(countInRange(N, L, R));          document.write( "<br>" ); Â
    // Input 2     let N1 = 5, L1 = 1, R1 = 100; Â
    // Function Call     document.write(countInRange(N1, L1, R1)); |
9 81
Time Complexity: O(N), Where N is the number of digits to be filled
Auxiliary Space: O(N)
Related Articles:
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!