Given three positive integers L, R and Y, the task is to count the numbers in the range [L, R] whose sum of digits is equal to Y
Examples:
Input: L = 500, R = 1000, Y = 6
Output: 3
Explanation:
Numbers in the range [500, 600] whose sum of digits is Y(= 6) are:
501 = 5 + 0 + 1 = 6
510 = 5 + 1 + 0 = 6
600 = 6 + 0 + 0 = 6
Therefore, the required output is 3.Input: L = 20, R = 10000, Y = 14
Output: 540
Naive Approach: Refer to previous post to solve this problem by iterating over all the numbers in the range [L, R], and for every number, check if its sum of digits is equal to Y or not. If found to be true, then increment the count. Finally, print the count obtained.
Time Complexity: O(R – L + 1) * log10(R)
Auxiliary Space: O(1)
Efficient approach: To optimize the above approach, the idea is to use Digit DP using the following recurrence relation:
where, sum: Represents sum of digits.
tight: Check if sum of digits exceed Y or not.
end: Stores the maximum possible value of ith digit of a number.
cntNum(N, Y, tight): Returns the count of numbers in the range [0, X] whose sum of digits is Y.
Before moving into the DP solution, it is good practice to write down the recursive code.
Here is the recursive code –
// C++ Program for the same approach #include <bits/stdc++.h> using namespace std;
// Function to find the sum of digits // of numbers in the range [0, X] int cntNum(string X, int i, int sum, int tight)
{ // Check if count of digits in a number
// greater than count of digits in X
if (i >= X.length() || sum < 0) {
// Check if sum of digits of a
// number is equal to Y
if (sum == 0) {
return 1;
}
return 0;
}
// Stores count of numbers whose
// sum of digits is Y
int res = 0;
// Check if the number
// exceeds Y or not
int end = tight != 0 ? X[i] - '0' : 9;
// Iterate over all possible
// values of i-th digits
for ( int j = 0; j <= end; j++) {
// Update res
res += cntNum(X, i + 1, sum - j,
(tight > 0 & (j == end)) ==
true ? 1 : 0);
}
// Return res
return res;
} // Utility function to count the numbers in // the range [L, R] whose sum of digits is Y static int UtilCntNumRange( int L, int R, int Y)
{ // Base Case
if (R == 0 && Y == 0) {
return 1;
}
// Stores numbers in the form // of its equivalent String
string str = to_string(R);
// Stores count of numbers
// in the range [0, R]
int cntR = cntNum(str, 0, Y,
1);
// Update str
str = to_string(L - 1);
// Stores count of numbers in
// the range [0, L - 1]
int cntL = cntNum(str, 0, Y,
1);
return (cntR - cntL);
} // Driver code int main()
{ int L = 20, R = 10000, Y = 14;
cout<<(UtilCntNumRange(L, R, Y));
} // This code is contributed by shinjanpatra |
// Java program for the above approach import java.util.*;
class GFG
{ // Function to find the sum of digits // of numbers in the range [0, X] static int cntNum(String X, int i, int sum,
int tight)
{
// Check if count of digits in a number
// greater than count of digits in X
if (i >= X.length() || sum < 0 ) {
// Check if sum of digits of a
// number is equal to Y
if (sum == 0 ) {
return 1 ;
}
return 0 ;
}
// Stores count of numbers whose
// sum of digits is Y
int res = 0 ;
// Check if the number
// exceeds Y or not
int end = tight != 0 ? X.charAt(i) - '0' : 9 ;
// Iterate over all possible
// values of i-th digits
for ( int j = 0 ; j <= end; j++) {
// Update res
res += cntNum(X, i + 1 , sum - j,
(tight > 0 & (j == end)) ==
true ? 1 : 0 );
}
// Return res
return res;
}
// Utility function to count the numbers in // the range [L, R] whose sum of digits is Y static int UtilCntNumRange( int L, int R, int Y)
{
// Base Case
if (R == 0 && Y == 0 ) {
return 1 ;
}
// Stores numbers in the form
// of its equivalent String
String str = String.valueOf(R);
// Stores count of numbers
// in the range [0, R]
int cntR = cntNum(str, 0 , Y,
1 );
// Update str
str = String.valueOf(L - 1 );
// Stores count of numbers in
// the range [0, L - 1]
int cntL = cntNum(str, 0 , Y,
1 );
return (cntR - cntL);
}
// Driver Code public static void main (String[] args)
{
int L = 20 , R = 10000 , Y = 14 ;
System.out.print(UtilCntNumRange(L, R, Y));
}
} // This code is contributed by Debojyoti Mandal |
# Python program for the above approach # Function to find the sum of digits # of numbers in the range [0, X] def cntNum(X, i, sum , tight):
# Check if count of digits in a number
# greater than count of digits in X
if (i > = len (X) or sum < 0 ):
# Check if sum of digits of a
# number is equal to Y
if ( sum = = 0 ):
return 1
return 0
# Stores count of numbers whose
# sum of digits is Y
res = 0
# Check if the number
# exceeds Y or not
end = ord (X[i]) - ord ( '0' ) if tight else 9
# Iterate over all possible
# values of i-th digits
for j in range (end + 1 ):
# Update res
res + = cntNum(X, i + 1 , sum - j, 1 if ((tight > 0 and (j = = end)) = = True ) else 0 )
# Return res
return res
# Utility function to count the numbers in # the range [L, R] whose sum of digits is Y def UtilCntNumRange(L, R, Y):
# Base Case
if (R = = 0 and Y = = 0 ):
return 1
# Stores numbers in the form
# of its equivalent String
Str = str (R)
# Stores count of numbers
# in the range [0, R]
cntR = cntNum( Str , 0 , Y, 1 )
# Update str
Str = str (L - 1 )
# Stores count of numbers in
# the range [0, L - 1]
cntL = cntNum( Str , 0 , Y, 1 )
return (cntR - cntL)
# Driver Code L, R, Y = 20 , 10000 , 14
print (UtilCntNumRange(L, R, Y))
# This code is contributed by shinjanpatra |
// C# program for the above approach using System;
class GFG
{ // Function to find the sum of digits
// of numbers in the range [0, X]
static int cntNum( string X, int i, int sum, int tight)
{
// Check if count of digits in a number
// greater than count of digits in X
if (i >= X.Length || sum < 0) {
// Check if sum of digits of a
// number is equal to Y
if (sum == 0) {
return 1;
}
return 0;
}
// Stores count of numbers whose
// sum of digits is Y
int res = 0;
// Check if the number
// exceeds Y or not
int end = tight != 0 ? X[i] - '0' : 9;
// Iterate over all possible
// values of i-th digits
for ( int j = 0; j <= end; j++) {
// Update res
res += cntNum(
X, i + 1, sum - j,
(tight > 0 & (j == end)) == true ? 1 : 0);
}
// Return res
return res;
}
// Utility function to count the numbers in
// the range [L, R] whose sum of digits is Y
static int UtilCntNumRange( int L, int R, int Y)
{
// Base Case
if (R == 0 && Y == 0) {
return 1;
}
// Stores numbers in the form
// of its equivalent String
string str = R.ToString();
// Stores count of numbers
// in the range [0, R]
int cntR = cntNum(str, 0, Y, 1);
// Update str
str = (L - 1).ToString();
// Stores count of numbers in
// the range [0, L - 1]
int cntL = cntNum(str, 0, Y, 1);
return (cntR - cntL);
}
// Driver Code
public static void Main( string [] args)
{
int L = 20, R = 10000, Y = 14;
Console.WriteLine(UtilCntNumRange(L, R, Y));
}
} // This code is contributed by ukasp. |
// JavaScript program for the above approach // Function to find the sum of digits // of numbers in the range [0, X] function cntNum( X, i, sum, tight)
{
// Check if count of digits in a number
// greater than count of digits in X
if (i >= X.length || sum < 0) {
// Check if sum of digits of a
// number is equal to Y
if (sum == 0) {
return 1;
}
return 0;
}
// Stores count of numbers whose
// sum of digits is Y
var res = 0;
// Check if the number
// exceeds Y or not
var end = tight != 0 ? X[i].charCodeAt(0) - '0' .charCodeAt(0) : 9;
// Iterate over all possible
// values of i-th digits
for ( var j = 0; j <= end; j++) {
// Update res
res += cntNum(X, i + 1, sum - j,
(tight > 0 & (j == end)) ==
true ? 1 : 0);
}
// Return res
return res;
}
// Utility function to count the numbers in // the range [L, R] whose sum of digits is Y function UtilCntNumRange(L, R, Y)
{
// Base Case
if (R == 0 && Y == 0) {
return 1;
}
// Stores numbers in the form
// of its equivalent String
var str = (R).toString();
// Stores count of numbers
// in the range [0, R]
var cntR = cntNum(str, 0, Y,
1);
// Update str
str = (L - 1).toString();
// Stores count of numbers in
// the range [0, L - 1]
var cntL = cntNum(str, 0, Y,
1);
return (cntR - cntL);
}
// Driver Code var L = 20, R = 10000, Y = 14;
document.write(UtilCntNumRange(L, R, Y));
// This code is contributed by shivanisinghss2110 |
Output
540
Follow the steps below to solve the problem using DP.
- Initialize a 3D array dp[N][Y][tight] to compute and store the values of all subproblems of the above recurrence relation.
- Finally, return the value of dp[N][sum][tight].
Below is the implementation of the above approach:
// CPP program for the above approach #include <bits/stdc++.h> using namespace std;
#define M 1000 // Function to find the sum of digits // of numbers in the range [0, X] int cntNum(string X, int i, int sum,
int tight, int dp[M][M][2])
{ // Check if count of digits in a number
// greater than count of digits in X
if (i >= X.length() || sum < 0) {
// If sum of digits of a
// number is equal to Y
if (sum == 0) {
return 1;
}
return 0;
}
// Check if current subproblem has
// already been computed
if (dp[sum][i][tight] != -1) {
return dp[sum][i][tight];
}
// Stores count of numbers whose
// sum of digits is Y
int res = 0;
// Check if the number
// exceeds Y or not
int end = tight ? X[i] - '0' : 9;
// Iterate over all possible
// values of i-th digits
for ( int j = 0; j <= end; j++) {
// Update res
res += cntNum(X, i + 1, sum - j,
(tight & (j == end)), dp);
}
// Return res
return dp[sum][i][tight]=res;
} // Utility function to count the numbers in // the range [L, R] whose sum of digits is Y int UtilCntNumRange( int L, int R, int Y)
{ // Base Case
if (R == 0 && Y == 0) {
return 1;
}
// Stores numbers in the form
// of its equivalent string
string str = to_string(R);
// Stores overlapping subproblems
int dp[M][M][2];
// Initialize dp[][][]
memset (dp, -1, sizeof (dp));
// Stores count of numbers
// in the range [0, R]
int cntR = cntNum(str, 0, Y,
true , dp);
// Update str
str = to_string(L - 1);
// Initialize dp[][][]
memset (dp, -1, sizeof (dp));
// Stores count of numbers in
// the range [0, L - 1]
int cntL = cntNum(str, 0, Y,
true , dp);
return (cntR - cntL);
} // Driver Code int main()
{ int L = 20, R = 10000, Y = 14;
cout << UtilCntNumRange(L, R, Y);
} |
// Java program for the above approach import java.util.*;
class GFG{
static final int M = 1000 ;
// Function to find the sum of digits // of numbers in the range [0, X] static int cntNum(String X, int i, int sum,
int tight, int dp[][][])
{ // Check if count of digits in a number
// greater than count of digits in X
if (i >= X.length() || sum < 0 ) {
// Check if sum of digits of a
// number is equal to Y
if (sum == 0 ) {
return 1 ;
}
return 0 ;
}
// Check if current subproblem has
// already been computed
if (dp[sum][i][tight] != - 1 ) {
return dp[sum][i][tight];
}
// Stores count of numbers whose
// sum of digits is Y
int res = 0 ;
// Check if the number
// exceeds Y or not
int end = tight != 0 ? X.charAt(i) - '0' : 9 ;
// Iterate over all possible
// values of i-th digits
for ( int j = 0 ; j <= end; j++) {
// Update res
res += cntNum(X, i + 1 , sum - j,
(tight > 0 & (j == end)) ==
true ? 1 : 0 , dp);
}
// Return res
return dp[sum][i][tight]=res;
} // Utility function to count the numbers in // the range [L, R] whose sum of digits is Y static int UtilCntNumRange( int L, int R, int Y)
{ // Base Case
if (R == 0 && Y == 0 ) {
return 1 ;
}
// Stores numbers in the form
// of its equivalent String
String str = String.valueOf(R);
// Stores overlapping subproblems
int [][][]dp = new int [M][M][ 2 ];
// Initialize dp[][][]
for ( int i = 0 ; i < M; i++)
{
for ( int j = 0 ; j < M; j++) {
for ( int k = 0 ; k < 2 ; k++)
dp[i][j][k] = - 1 ;
}
}
// Stores count of numbers
// in the range [0, R]
int cntR = cntNum(str, 0 , Y,
1 , dp);
// Update str
str = String.valueOf(L - 1 );
// Initialize dp[][][]
for ( int i = 0 ; i < M; i++)
{
for ( int j = 0 ; j < M; j++) {
for ( int k = 0 ; k < 2 ; k++)
dp[i][j][k] = - 1 ;
}
}
// Stores count of numbers in
// the range [0, L - 1]
int cntL = cntNum(str, 0 , Y,
1 , dp);
return (cntR - cntL);
} // Driver Code public static void main(String[] args)
{ int L = 20 , R = 10000 , Y = 14 ;
System.out.print(UtilCntNumRange(L, R, Y));
} } // This code is contributed by shikhasingrajput |
# Python program for the above approach M = 1000
# Function to find the sum of digits # of numbers in the range [0, X] def cntNum(X, i, sum , tight, dp):
# Check if count of digits in a number
# greater than count of digits in X
if (i > = len (X) or sum < 0 ):
# Check if sum of digits of a
# number is equal to Y
if ( sum = = 0 ):
return 1
return 0
# Check if current subproblem has
# already been computed
if (dp[ sum ][i][tight] ! = - 1 ):
return dp[ sum ][i][tight]
# Stores count of numbers whose
# sum of digits is Y
res, end = 0 , 9
# Check if the number
# exceeds Y or not
if tight:
end = ord (X[i]) - ord ( '0' )
# end = tight ? X[i] - '0' : 9;
# Iterate over all possible
# values of i-th digits
for j in range (end + 1 ):
# Update res
res + = cntNum(X, i + 1 , sum - j,
(tight & (j = = end)), dp)
# Return res
dp[ sum ][i][tight] = res
return res
# Utility function to count the numbers in # the range [L, R] whose sum of digits is Y def UtilCntNumRange(L, R, Y):
# Base Case
if (R = = 0 and Y = = 0 ):
return 1
# Stores numbers in the form
# of its equivalent
strr = str (R)
# Stores overlapping subproblems
dp = [[[ - 1 for i in range ( 2 )] for i in range (M)]
for i in range (M)]
# Initialize dp[][][]
# memset(dp, -1, sizeof(dp))
# Stores count of numbers
# in the range [0, R]
cntR = cntNum(strr, 0 , Y, True , dp)
# Update str
strr = str (L - 1 )
# Initialize dp[][][]
# memset(dp, -1, sizeof(dp))
# Stores count of numbers in
# the range [0, L - 1]
cntL = cntNum(strr, 0 , Y, True , dp)
return (cntR - cntL)
# Driver Code if __name__ = = '__main__' :
L, R, Y = 20 , 10000 , 14
print (UtilCntNumRange(L, R, Y))
# This code is contributed by mohit kumar 29 |
// C# program for the above approach using System;
class GFG{
static readonly int M = 1000;
// Function to find the sum of digits // of numbers in the range [0, X] static int cntNum(String X, int i, int sum,
int tight, int [,,]dp)
{ // Check if count of digits in a number
// greater than count of digits in X
if (i >= X.Length || sum < 0)
{
// Check if sum of digits of a
// number is equal to Y
if (sum == 0)
{
return 1;
}
return 0;
}
// Check if current subproblem has
// already been computed
if (dp[sum, i, tight] != -1)
{
return dp[sum, i, tight];
}
// Stores count of numbers whose
// sum of digits is Y
int res = 0;
// Check if the number
// exceeds Y or not
int end = tight != 0 ? X[i] - '0' : 9;
// Iterate over all possible
// values of i-th digits
for ( int j = 0; j <= end; j++)
{
// Update res
res += cntNum(X, i + 1, sum - j,
(tight > 0 & (j == end)) ==
true ? 1 : 0, dp);
}
// Return res
return dp[sum][i][tight] = res;
} // Utility function to count the numbers in // the range [L, R] whose sum of digits is Y static int UtilCntNumRange( int L, int R, int Y)
{ // Base Case
if (R == 0 && Y == 0)
{
return 1;
}
// Stores numbers in the form
// of its equivalent String
String str = String.Join( "" , R);
// Stores overlapping subproblems
int [,,]dp = new int [M, M, 2];
// Initialize [,]dp[]
for ( int i = 0; i < M; i++)
{
for ( int j = 0; j < M; j++)
{
for ( int k = 0; k < 2; k++)
dp[i, j, k] = -1;
}
}
// Stores count of numbers
// in the range [0, R]
int cntR = cntNum(str, 0, Y,
1, dp);
// Update str
str = String.Join( "" ,L - 1);
// Initialize [,]dp[]
for ( int i = 0; i < M; i++)
{
for ( int j = 0; j < M; j++)
{
for ( int k = 0; k < 2; k++)
dp[i, j, k] = -1;
}
}
// Stores count of numbers in
// the range [0, L - 1]
int cntL = cntNum(str, 0, Y,
1, dp);
return (cntR - cntL);
} // Driver Code public static void Main(String[] args)
{ int L = 20, R = 10000, Y = 14;
Console.Write(UtilCntNumRange(L, R, Y));
} } // This code is contributed by 29AjayKumar |
<script> // Javascript program for the above approach let M = 1000; // Function to find the sum of digits // of numbers in the range [0, X] function cntNum(X, i, sum, tight, dp)
{ // Check if count of digits in a number
// greater than count of digits in X
if (i >= X.length || sum < 0) {
// Check if sum of digits of a
// number is equal to Y
if (sum == 0) {
return 1;
}
return 0;
}
// Check if current subproblem has
// already been computed
if (dp[sum][i][tight] != -1) {
return dp[sum][i][tight];
}
// Stores count of numbers whose
// sum of digits is Y
let res = 0;
// Check if the number
// exceeds Y or not
let end = tight != 0 ? X[i].charCodeAt(0) - '0' .charCodeAt(0) : 9;
// Iterate over all possible
// values of i-th digits
for (let j = 0; j <= end; j++) {
// Update res
res += cntNum(X, i + 1, sum - j,
(tight > 0 & (j == end)) ==
true ? 1 : 0, dp);
}
// Return res
return dp[sum][i][tight]=res;
} // Utility function to count the numbers in // the range [L, R] whose sum of digits is Y function UtilCntNumRange(L,R,Y)
{ // Base Case
if (R == 0 && Y == 0) {
return 1;
}
// Stores numbers in the form
// of its equivalent String
let str = (R).toString();
// Stores overlapping subproblems
let dp = new Array(M);
// Initialize dp[][][]
for (let i = 0; i < M; i++)
{
dp[i]= new Array(M);
for (let j = 0; j < M; j++) {
dp[i][j]= new Array(2);
for (let k = 0; k < 2; k++)
dp[i][j][k] = -1;
}
}
// Stores count of numbers
// in the range [0, R]
let cntR = cntNum(str, 0, Y,
1, dp);
// Update str
str = (L - 1).toString();
// Initialize dp[][][]
for (let i = 0; i < M; i++)
{
for (let j = 0; j < M; j++) {
for (let k = 0; k < 2; k++)
dp[i][j][k] = -1;
}
}
// Stores count of numbers in
// the range [0, L - 1]
let cntL = cntNum(str, 0, Y,
1, dp);
return (cntR - cntL);
} // Driver Code let L = 20, R = 10000, Y = 14; document.write(UtilCntNumRange(L, R, Y)); // This code is contributed by patel2127 </script> |
Output
540
Time Complexity: O(Y * log10(R) * 10)
Auxiliary Space: O(Y * log10(R)