Count of Integers - Digit DP [JS]
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
Post a Comment