Leetcode 3747. Count Distinct Integers After Removing Zeros

1. 解题思路

这一题是Leetcode周赛476的第三题,是一道medium的题目。

这一题思路上就是一个动态规划的思路,就是考察比 n n n小的所有不带有 0 0 0的整数的数目,这个我们只需要考察每一位上能够有的选项即可。

不过,这里我们需要注意几个特殊情况:

  • 当前位置之前是否已经至少有一个位置上元素非零;
  • 当前位置之前是否已经至少有一个位置上元素严格小于目标值,即当前位置是否可以随意分配元素。

在这两个情况的基础上,我们使用动态规划进行枚举即可。

2. 代码实现

给出python代码实现如下:

class Solution:
    def countDistinct(self, n: int) -> int:
        
        s = str(n)
        l = len(s)

        @lru_cache(None)
        def dp(idx, allow_bigger, is_zero):
            if idx >= l:
                return 1 if not is_zero else 0
            if allow_bigger:
                if is_zero:
                    ans = 0
                    for i in range(1, l-idx+1):
                        ans += 9**i
                    return ans
                else:
                    return 9**(l-idx)
            elif s[idx] == '0':
                return 0
            elif is_zero:
                return dp(idx+1, True, True) + (int(s[idx])-1) * dp(idx+1, True, False) + dp(idx+1, False, False)
            else:
                return (int(s[idx])-1) * dp(idx+1, True, False) + dp(idx+1, False, False)

        return dp(0, False, True)

提交代码评测得到:耗时6ms,占用内存18.12MB。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值