Day 23
Date: October 18, 2022 1:26 PM
LinkedIn: https://leetcode.cn/problems/numbers-at-most-n-given-digit-set/description/
Title: 最大为 N 的数字组合
本题参考的题解,但还不是特别懂,记录一下, 第一次接触记忆化这种,本题不用@cache就会超时
class Solution:
def atMostNGivenDigitSet(self, digits: List[str], n: int) -> int:
# 深度优先遍历
@cache # 记忆化(是一种提高计算机程序执行速度的优化技术),通过储存大计算量函数的返回值,当这个结果再次被需要时将其从缓存提取,而不用再次计算来节省计算时间。
def dfs(pos, lead, limit):# pos为当前数字位置,lead为当前数中有前导零,limit是是否需要限制可填的数字
if pos <= 0:
return lead == False # 到最后一位数字若为
up = a[pos] if limit else 9 # 类似于if limit:up = a[pos] else: up = 9
ans = 0 # 计算满足条件的个数
for i in range(up + 1): # 0到n的循环
if i == 0 and lead: # i为0且当前数中可以有前导0 , 那么i=0可以放入当前数字位置
ans += dfs(pos - 1, lead, limit and i == up) # 如果limit为True且已经取到了能取到的最大值那么下一个limit为True 如果limit 为True 但还没到最大,或者limit为false 那么下一个limit为False
elif i in s:
ans += dfs(pos - 1, False, limit and i == up) # i不为0那么下一个就没有前导0了
return ans
index = 0 # a数组的下标
a = [0] * 12 # n <= 10^9 需要下标从1开始
s = {int(d) for d in digits} # 将所给digits转换为int型并存储到s数组
while n:# 取n的各个位数
index += 1
a[index] = n % 10
n //= 10 # //=取整除法
return dfs(index, True, True) # 从下标最大开始也就是最高位开始,当前数中有前导零初始为True,当前数可以为0,limit初始为True,最高位肯定要限制