力扣每日一题 最大为 N 的数字组合

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,最高位肯定要限制

你可能感兴趣的:(力扣每日一题,Python,leetcode,算法,深度优先)