Use this to learn the idea, then write your own version.
123 45class Solution(object):6 def numberOfBeautifulIntegers(self, low, high, k):7 """8 :type low: int9 :type high: int10 :type k: int11 :rtype: int12 """13 TIGHT, UNTIGHT, UNBOUND = range(3)14 def f(x):15 digits = map(int, str(x))16 lookup = [[[[-1]*k for _ in xrange(2*len(digits)+1)] for _ in xrange(3)] for _ in xrange(len(digits))]17 def memoization(i, state, diff, total):18 if i == len(digits):19 return int(state != UNBOUND and diff == total == 0)20 if lookup[i][state][diff][total] == -1:21 result = int(i != 0 and diff == total == 0) 22 for d in xrange(1 if i == 0 else 0, 10):23 new_state = state24 if state == TIGHT and d != digits[i]:25 new_state = UNTIGHT if d < digits[i] else UNBOUND26 new_diff = diff+(1 if d%2 == 0 else -1)27 new_total = (total*10+d)%k28 result += memoization(i+1, new_state, new_diff, new_total)29 lookup[i][state][diff][total] = result30 return lookup[i][state][diff][total]31 32 return memoization(0, TIGHT, 0, 0)33 34 return f(high)-f(low-1)35 36 37383940class Solution2(object):41 def numberOfBeautifulIntegers(self, low, high, k):42 """43 :type low: int44 :type high: int45 :type k: int46 :rtype: int47 """48 TIGHT, UNTIGHT, UNBOUND = range(3)49 def f(x):50 digits = map(int, str(x))51 dp = [[[0]*k for _ in xrange(2*len(digits)+1)] for _ in xrange(3)]52 for tight in xrange(2):53 for state in (TIGHT, UNTIGHT):54 dp[state][0][0] = 155 for i in reversed(xrange(len(digits))):56 new_dp = [[[0]*k for _ in xrange(2*len(digits)+1)] for _ in xrange(3)]57 for state in (TIGHT, UNTIGHT, UNBOUND):58 new_dp[state][0][0] = int(i != 0) 59 for d in xrange(1 if i == 0 else 0, 10):60 new_state = state61 if state == TIGHT and d != digits[i]:62 new_state = UNTIGHT if d < digits[i] else UNBOUND63 for diff in xrange(-len(digits), len(digits)+1):64 new_diff = diff+(1 if d%2 == 0 else -1)65 for total in xrange(k):66 new_total = (total*10+d)%k67 new_dp[state][diff][total] += dp[new_state][new_diff][new_total]68 dp = new_dp69 return dp[TIGHT][0][0]70 71 return f(high)-f(low-1)72 73 74757677class Solution3(object):78 def numberOfBeautifulIntegers(self, low, high, k):79 """80 :type low: int81 :type high: int82 :type k: int83 :rtype: int84 """85 def f(x):86 digits = map(int, str(x))87 lookup = [[[[[-1]*k for _ in xrange(2*len(digits)+1)] for _ in xrange(2)] for _ in xrange(2)] for _ in xrange(len(digits))]88 def memoization(i, zero, tight, diff, total):89 if i == len(digits):90 return int(zero == diff == total == 0)91 if lookup[i][zero][tight][diff][total] == -1:92 result = 093 for d in xrange((digits[i] if tight else 9)+1):94 new_zero = int(zero and d == 0)95 new_tight = int(tight and d == digits[i])96 new_diff = diff+((1 if d%2 == 0 else -1) if new_zero == 0 else 0)97 new_total = (total*10+d)%k98 result += memoization(i+1, new_zero, new_tight, new_diff, new_total)99 lookup[i][zero][tight][diff][total] = result100 return lookup[i][zero][tight][diff][total]101 102 return memoization(0, 1, 1, 0, 0)103 104 return f(high)-f(low-1)105 106 107108109110class Solution4(object):111 def numberOfBeautifulIntegers(self, low, high, k):112 """113 :type low: int114 :type high: int115 :type k: int116 :rtype: int117 """118 def f(x):119 digits = map(int, str(x))120 dp = [[[[0]*k for _ in xrange(2*len(digits)+1)] for _ in xrange(2)] for _ in xrange(2)]121 for tight in xrange(2):122 dp[0][tight][0][0] = 1123 for i in reversed(xrange(len(digits))):124 new_dp = [[[[0]*k for _ in xrange(2*len(digits)+1)] for _ in xrange(2)] for _ in xrange(2)]125 for zero in xrange(2):126 for tight in xrange(2):127 for d in xrange((digits[i] if tight else 9)+1):128 new_zero = int(zero and d == 0)129 new_tight = int(tight and d == digits[i])130 for diff in xrange(-len(digits), len(digits)+1):131 new_diff = diff+((1 if d%2 == 0 else -1) if new_zero == 0 else 0)132 for total in xrange(k):133 new_total = (total*10+d)%k134 new_dp[zero][tight][diff][total] += dp[new_zero][new_tight][new_diff][new_total]135 dp = new_dp136 return dp[1][1][0][0]137 138 return f(high)-f(low-1)139