The solution uses a digit dynamic programming approach to efficiently count numbers within a specific range whose digit sum falls between given bounds. It considers two main functions: 1) 'ndn(n, dsum)', which calculates how many n-digit numbers have a digit sum exactly equal to 'dsum'. 2) 'ddn(num, max_sum)', which calculates the count of numbers up to 'num' that have a digit sum of at most 'max_sum'. The main idea is to count the numbers satisfying the conditions up to 'num2' and subtract the count of numbers up to 'num1' - 1 (thus counting numbers between 'num1' and 'num2'), and adjust this for the specified digit sum range.
时间复杂度: O(D^2 * 10 * max_sum) where D is the number of digits in 'num2'. This complexity stems from the iteration over all possible first digits and recursive processing for each subsequent digit.
空间复杂度: O(D * max_sum), which accounts for the maximum depth of recursion multiplied by the range of digit sums cached.
class Solution:
def count(self, num1: str, num2: str, min_sum: int, max_sum: int) -> int:
MOD = 1_000_000_007
num1 = str(int(num1) - 1) # Convert num1 to one less to include it in range during subtraction
n = len(num2)
num1 = '0' * (n - len(num1)) + num1 # Pad num1 to match the length of num2
num1, num2 = tuple(map(int, num1)), tuple(map(int, num2)) # Convert strings to tuple of digits
@cache
def ndn(n, dsum): # Count of n-digit numbers with digit sum exactly 'dsum'
if dsum < 0: return 0
if n == 0: return 1 # Base case: one way (the number 0)
res = 0
for cd in range(10): # Loop through each digit from 0 to 9
res = (res + ndn(n-1, dsum-cd)) % MOD
return res
def ddn(num, max_sum): # Dynamic digit sum calculation up to 'num'
if max_sum < 0: return 0
if not num: return 1 # Base case: one way if no digits left
res = 0
for cd in range(num[0]): # Try all digits less than the first digit of num
res = (res + ndn(len(num)-1, max_sum-cd)) % MOD
return (res + ddn(num[1:], max_sum-num[0])) % MOD # Include the case where first digit is num[0]
return ((ddn(num2, max_sum) - ddn(num2, min_sum-1)) - (ddn(num1, max_sum) - ddn(num1, min_sum-1))) % MOD