Count of Integers
HardPrompt
You are given two numeric strings num1 and num2 and two integers max_sum and min_sum. We denote an integer x to be good if:
num1 <= x <= num2min_sum <= digit_sum(x) <= max_sum.
Return the number of good integers. Since the answer may be large, return it modulo 109 + 7.
Note that digit_sum(x) denotes the sum of the digits of x.
Example 1:
min_sumExample 2:
min_sum
Constraints:
1 <= num1 <= num2 <= 10221 <= min_sum <= max_sum <= 400
Approaches
2 approaches with complexity analysis and trade-offs.
The most straightforward approach is to simulate the process directly. We can iterate through every integer x from num1 to num2, calculate the sum of its digits, and check if this sum falls within the given [min_sum, max_sum] range. If it does, we increment a counter. Due to the massive size of num1 and num2 (up to 10^22), we must use a data type that can handle arbitrarily large integers, such as BigInteger in Java.
Algorithm
- Initialize a counter
countto 0. - Use
BigIntegerto handle the large numbersnum1andnum2. - Create a loop that iterates from
num1tonum2, incrementing by one in each step. - For each number in the loop:
a. Convert the
BigIntegerto a string. b. Calculate the sum of its digits by iterating through the string characters. c. Check if the calculated digit sum lies within the range[min_sum, max_sum]. d. If the condition is true, increment thecount. - After the loop finishes, return the final
count.
Walkthrough
This method involves a simple loop from the starting number num1 to the ending number num2. For each number, we perform a check. The check consists of two parts: calculating the digit sum and comparing it with min_sum and max_sum. While simple to conceptualize, the number of iterations can be enormous, making this approach computationally infeasible for the constraints of the problem.
import java.math.BigInteger; // This is a conceptual example that will time out.class Solution { public int count(String num1, String num2, int min_sum, int max_sum) { BigInteger current = new BigInteger(num1); BigInteger end = new BigInteger(num2); long count = 0; int MOD = 1_000_000_007; while (current.compareTo(end) <= 0) { if (isGood(current, min_sum, max_sum)) { count++; } current = current.add(BigInteger.ONE); } // The count can be large, but the problem asks for the final result modulo 10^9+7. // However, since we can't even finish the loop, this is a moot point. return (int)(count % MOD); } private boolean isGood(BigInteger n, int min_sum, int max_sum) { String s = n.toString(); int sum = 0; for (char c : s.toCharArray()) { sum += c - '0'; if (sum > max_sum) { // Small optimization return false; } } return sum >= min_sum && sum <= max_sum; }}Complexity
Time
O((num2 - num1) * L), where L is the average number of digits in the numbers in the range. Given that `num2` can be up to 10^22, this is far too slow.
Space
O(L), where L is the number of digits in `num2`. This space is required to store the `BigInteger` representation of the current number.
Trade-offs
Pros
Easy to understand and implement.
Correct for small ranges of
num1andnum2.
Cons
Extremely inefficient and will cause a 'Time Limit Exceeded' error on any platform for the given constraints.
The difference between
num2andnum1can be very large (up to 10^22), making iteration impossible.
Solutions
Solution
import java.math.BigInteger ; class Solution { private final int mod = ( int ) 1 e9 + 7 ; private Integer [][] f ; private String num ; private int min ; private int max ; public int count ( String num1 , String num2 , int min_sum , int max_sum ) { min = min_sum ; max = max_sum ; num = num2 ; f = new Integer [ 23 ][ 220 ]; int a = dfs ( 0 , 0 , true ); num = new BigInteger ( num1 ). subtract ( BigInteger . ONE ). toString (); f = new Integer [ 23 ][ 220 ]; int b = dfs ( 0 , 0 , true ); return ( a - b + mod ) % mod ; } private int dfs ( int pos , int s , boolean limit ) { if ( pos >= num . length ()) { return s >= min && s <= max ? 1 : 0 ; } if (! limit && f [ pos ][ s ] != null ) { return f [ pos ][ s ]; } int ans = 0 ; int up = limit ? num . charAt ( pos ) - '0' : 9 ; for ( int i = 0 ; i <= up ; ++ i ) { ans = ( ans + dfs ( pos + 1 , s + i , limit && i == up )) % mod ; } if (! limit ) { f [ pos ][ s ] = ans ; } return ans ; } }Video walkthrough
Newsletter
One sharp idea, every week
System design and interview prep — short enough to finish.
No spam. Unsubscribe anytime.
Practice
Same difficulty — related problems to reinforce the pattern.