题目:
如果一个正整数每一个数位都是 互不相同 的,我们称它是 特殊整数 。
给你一个 正 整数 n ,请你返回区间 [1, n] 之间特殊整数的数目。
示例 1:
输入:n = 20
输出:19
解释:1 到 20 之间所有整数除了 11 以外都是特殊整数。所以总共有 19 个特殊整数。
示例 2:
输入:n = 5
输出:5
解释:1 到 5 所有整数都是特殊整数。
示例 3:
输入:n = 135
输出:110
解释:从 1 到 135 总共有 110 个整数是特殊整数。
不特殊的部分数字为:22 ,114 和 131 。
思路:
- 数位DP
- 集合说明

解答:
class Solution:
def countSpecialNumbers(self, n: int) -> int:
s=str(n)
# 数位DP
# 返回从i位开始填数字,i前面填的数字的集合是mask,能构造出的特殊整数的个数
# is_limit 表示前面填的数字是否都是n对应位上的,如果为true,那么当前位至多为int(s[i]),否则为9
# is_num 表示前面是否填了数字,如果为true,那么当前位可以从0开始;如果为false,那么我们可以跳过,或者从1开始填数字
@cache
def f(i,mask,is_limit,is_num):
if i==len(s):
return int(is_num)
res=0
if not is_num: #选择跳过,不填数字
res=f(i+1,mask,False,False)
up=int(s[i]) if is_limit else 9
#枚举要填的数字,枚举的范围就取决于is_limit 和is_num
for d in range(1-int(is_num),up+1):
if mask>>d & 1==0: #mask里面没有d,则d可选
res+=f(i+1,mask|(1<<d),is_limit and d==up,True)
return res
return f(0,0,True,False)

该问题要求计算从1到给定正整数n之间,每个数位都不同的整数(特殊整数)的数量。解决方案采用数位动态规划(DP),通过递归函数f(i,mask,is_limit,is_num)计算在不同状态下的特殊整数个数,其中mask表示已使用的数字,is_limit和is_num控制填充数字的范围。最后返回f(0,0,True,False)作为答案。
797

被折叠的 条评论
为什么被折叠?



