假设我们的数字限制的长度为K,则我们从右往左(位数从低到高)开始处理,遍历digits中的数字,被遍历到的数字小于限制数字的对应位置(假设为第i位)的数字时,则其右侧的数字(i+1位以后)可以从digits中任意选择,总共组合数字也就是len(digits)**(k-1-i)。而如果当前数字和限制数字的第i位相等,则我们依然可以第i+1位之后的数字里,看从digits中选择组成的数字有多少种满足条件,也就是dp[i+1]。这样的选择加上一个与第i位数字相等的数字的组合数字依然是dp[i+1]。于是我们得到全部的状态转移方程。最后我们返回dp[0]的意思是我们的N长度的数字里,每一位数字都从digits里选择了,有多少种,但是,这样计算我们还没有计算假设我们只组成了长度为1,2,3—K-1的有多少。因为随意选择,其长度都短于K,小于限制数字,这样的组合也要被加到最后的结果里。
class Solution:
def atMostNGivenDigitSet(self, digits: List[str], n: int) -> int:
lenofdigit = len(digits)
stringofn = str(n)
k = len(stringofn)
dp = [0]*k + [1]
for i in range(k-1, -1, -1):
for num in digits:
if num < stringofn[i]:
dp[i] += lenofdigit**(k-1-i)
elif num == stringofn[i]:
dp[i] += dp[i+1]
return dp[0] + sum([lenofdigit**i for i in range(1,k)])