- Define precisely what one DP state represents.
- Establish the base cases before transitions are evaluated.
- Process states in dependency order and combine only already-known values.
Code notes
- 102 lines of Python from the credited upstream file number-of-balanced-integers-in-a-range.py.
- The implementation visibly relies on sequence storage, cached states.
- No explicit loop blocks detected.
Complexity
Multiply the number of reachable states by the work performed for each transition, then include the stored state table in memory usage.
Check the problem constraints before deciding whether this complexity will pass.
Use this to learn the idea, then write your own version.
123 45class Solution(object):6 def countBalanced(self, low, high):7 """8 :type low: int9 :type high: int10 :rtype: int11 """12 def count(n):13 digits = []14 while n:15 n, r = divmod(n, 10)16 digits.append(r)17 digits.reverse()18 dp = [[0]*2 for _ in xrange(len(digits)*9+1)]19 dp[0][1] = 120 for i in xrange(len(digits)):21 new_dp = [[0]*2 for _ in xrange(len(digits)*9+1)]22 for curr in xrange(len(dp)):23 curr -= len(digits)2*924 for tight in xrange(2):25 if not dp[curr][tight]:26 continue27 bound = digits[i] if tight else 928 for d in xrange(bound+1):29 new_dp[curr-d if i&1 else curr+d][tight and d == bound] += dp[curr][tight]30 dp = new_dp31 return dp[0][0]32 33 return count(high+1)-count(low)34 35 36373839class Solution2(object):40 def countBalanced(self, low, high):41 """42 :type low: int43 :type high: int44 :rtype: int45 """46 def count(n):47 digits = []48 while n:49 n, r = divmod(n, 10)50 digits.append(r)51 digits.reverse()52 memo = [[-1]*(len(digits)*9+1) for _ in xrange(len(digits))]53 def memoization(i, curr, tight):54 if i == len(digits):55 return curr == 056 if not tight and memo[i][curr] != -1:57 return memo[i][curr]58 bound = digits[i] if tight else 959 result = 060 for d in xrange(bound+1):61 result += memoization(i+1, curr-d if i&1 else curr+d, tight and d == bound)62 if not tight:63 memo[i][curr] = result64 return result65 66 return memoization(0, 0, True)67 68 return count(high)-count(low-1)69 70 71727374class Solution3(object):75 def countBalanced(self, low, high):76 """77 :type low: int78 :type high: int79 :rtype: int80 """81 def count(n):82 digits = []83 while n:84 n, r = divmod(n, 10)85 digits.append(r)86 digits.reverse()87 memo = [[[-1]*2 for _ in xrange(len(digits)*9+1)] for _ in xrange(len(digits))]88 def memoization(i, curr, tight):89 if i == len(digits):90 return int(curr == 0)91 if memo[i][curr][tight] == -1:92 bound = digits[i] if tight else 993 result = 094 for d in xrange(bound+1):95 result += memoization(i+1, curr-d if i&1 else curr+d, tight and d == bound)96 memo[i][curr][tight] = result97 return memo[i][curr][tight]98 99 return memoization(0, 0, True)100 101 return count(high)-count(low-1)102