Count of Integers - Digit DP [JS]

Description 

Solution: Digit DP

Memoize each dp(i, state1, state2, digitSum), where

  • i = index of current digit
  • state1 = state of current number compared to num1 (0 = smaller, 1 = equal, 2 = greater)
  • state2 = state of current number compared to num2 (0 = smaller, 1 = equal, 2 = greater)
  • digitSum = current digit sum

For each dp(i, state1, state2, digitSum), try each possible digit as the next digit.
Compute the new states compared to num1 and num2.

Time Complexity: O(len(num2) * max_sum * 9)
Space Complexity: O(len(num2) * max_sum * 9)

var count = function(num1, num2, min_sum, max_sum) {
  let memo = new Map(), MOD = 10 ** 9 + 7;
  return dp(0, 1, 1, 0);
  
  function dp(i, state1, state2, digitSum) {
    if (i === num2.length) return state1 > 0 && state2 < 2 && digitSum >= min_sum && digitSum <= max_sum ? 1 : 0;
    let key = `${i},${state1},${state2},${digitSum}`;
    if (memo.has(key)) return memo.get(key);
    
    let ans = (i > num1.length || (i === num1.length && state1 > 0)) && digitSum >= min_sum && digitSum <= max_sum ? 1 : 0;
    for (let digit = 0; digit <= 9; digit++) {
      if (i === 0 && digit === 0) continue;
      let newState1 = getState(i, state1, digit, num1);
      let newState2 = getState(i, state2, digit, num2);
      ans = (ans + dp(i + 1, newState1, newState2, digitSum + digit)) % MOD;
    }
    memo.set(key, ans);
    return ans;
  }  
  
  function getState(i, state, digit, num) {
    if (i >= num.length) return 2;
    if (state === 0 || state === 2) return state;
    if (digit > Number(num[i])) return 2;
    if (digit === Number(num[i])) return 1;
    return 0;
  }
};

Comments

Popular posts from this blog

Maximum Value of an Ordered Triplet II - Two Solutions [JS]

Maximum Sum of Distinct Subarrays With Length K - Sliding Window w/ Two Pointers & Set [JS]

Sum of Prefix Scores of Strings - Trie [JS]

Maximum Count of Positive Integer and Negative Integer - Binary Search [JS]

Count Subarrays With Median K - Count Left & Right Balance [JS]