Count numbers that does not contain digit N in given range
Last Updated :
13 Feb, 2023
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));
Time Complexity: O(N), Where N is the number of digits to be filled
Auxiliary Space: O(N)
Related Articles:
Similar Reads
Count of Numbers in Range where the number does not contain more than K non zero digits Given a range represented by two positive integers L and R and a positive integer K. Find the count of numbers in the range where the number does not contain more than K non zero digits.Examples: Input : L = 1, R = 1000, K = 3 Output : 1000 Explanation : All the numbers from 1 to 1000 are 3 digit nu
11 min read
Count of numbers in a range that does not contain the digit M and which is divisible by M. Given three integers, the lower range L, the upper range U, and a digit M. The task is to count all the numbers between L and U such that the number is divisible by M and, also, it does not contain the digit M. Examples: Input: M = 9 ,L = 16 , U = 26 Output: 1 Explanation: Within this given range ,t
5 min read
Count numbers less than N containing digits from the given set : Digit DP Given an integer N and set of digits D[], which consists of digits from [1, 9]. The task is to count the numbers possible less than N, whose digits are from the given set of digits. Examples: Input: D = ["1", "4", "9"], N = 10 Output: 3 Explanation: There are only 3 numbers possible less than 3 with
13 min read
Count of numbers with all digits same in a given range Given two integers L and R denoting the starting and end values of a range, the task is to count all numbers in that range whose all digit are same, like 1, 22, 444, 3333, etc.Example: Input: L = 12, R = 68 Output: 5 Explanation: { 22, 33, 44, 55, 66} are the numbers with same digits in the given ra
9 min read
Count n digit numbers not having a particular digit We are given two integers n and d, we need to count all n digit numbers that do not have digit d. Example : Input : n = 2, d = 7 Output : 72 All two digit numbers that don't have 7 as digit are 10, 11, 12, 13, 14, 15, 16, 18, ..... Input : n = 3, d = 9 Output : 648 A simple solution is to traverse t
8 min read
Number of n digit numbers that do not contain 9 Given a number n, find how many n digit number can be formed that does not contain 9 as it's digit.Examples: Input : 1 Output : 8 Explanation : Except 9, all numbers are possible Input : 2 Output : 72 Explanation : Except numbers from 90 - 99 and all two digit numbers that does not end with 9 are po
3 min read