Skip to content

2719. Count of Integers 👍

  • Time: $O(|\texttt{num2}| \cdot \texttt{max\_sum} \cdot 2^2 \cdot 10)$
  • Space: $O(|\texttt{num2}| \cdot \texttt{max\_sum} \cdot 2^2)$
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
class Solution {
 public:
  int count(string num1, string num2, int min_sum, int max_sum) {
    const string num1WithLeadingZeros =
        string(num2.length() - num1.length(), '0') + num1;
    vector<vector<vector<vector<int>>>> mem(
        num2.length(),
        vector<vector<vector<int>>>(
            max_sum + 1, vector<vector<int>>(2, vector<int>(2, -1))));
    return (count(num1WithLeadingZeros, num2, 0, max_sum, true, true, mem) -
            count(num1WithLeadingZeros, num2, 0, min_sum - 1, true, true, mem) +
            kMod) %
           kMod;
  }

 private:
  static constexpr int kMod = 1'000'000'007;

  // Returns the number of valid integers, considering the i-th digit, where
  // `sum` is the maximum digit sum, `isTight1` indicates if the current digit
  // is tightly bound for `num1` and `isTight2` indicates if the current digit
  // is tightly bound for `num2`
  int count(const string& num1, const string& num2, int i, int sum,
            bool isTight1, bool isTight2,
            vector<vector<vector<vector<int>>>>& mem) {
    if (sum < 0)
      return 0;
    if (i == num2.length())
      return 1;
    if (mem[i][sum][isTight1][isTight2] != -1)
      return mem[i][sum][isTight1][isTight2];

    int res = 0;

    const int minDigit = isTight1 ? num1[i] - '0' : 0;
    const int maxDigit = isTight2 ? num2[i] - '0' : 9;
    for (int d = minDigit; d <= maxDigit; ++d) {
      const bool nextIsTight1 = isTight1 && (d == minDigit);
      const bool nextIsTight2 = isTight2 && (d == maxDigit);
      res += count(num1, num2, i + 1, sum - d, nextIsTight1, nextIsTight2, mem);
      res %= kMod;
    }

    return mem[i][sum][isTight1][isTight2] = res;
  }
};