Leetcode 357.计算各个位数不同的数字个数(Count Numbers with Unique Digits)

Leetcode 357.计算各个位数不同的数字个数

1 题目描述(Leetcode题目链接)

  给定一个非负整数 n,计算各位数字都不同的数字 x 的个数,其中 0 ≤ x < 1 0 n 0 ≤ x < 10^n 0x<10n

输入: 2
输出: 91 
解释: 答案应为除去 11,22,33,44,55,66,77,88,99 外,在 [0,100) 区间内的所有数字。

2 题解

  动态规划,首先 n = 0 n=0 n=0时,就只有一个数, n = 1 n=1 n=1时都是个位数,因此就是 10 10 10 n = 2 n=2 n=2开始,数的个数增加了 n n n位数,比如 n = 2 n=2 n=2时增加的是 [ 10 , 99 ] [10,99] [10,99] n = 3 n=3 n=3时增加的是 [ 100 , 999 ] [100,999] [100,999]

  因此我们定义 d p [ i ] dp[i] dp[i]表示 n = i n=i n=i时各个位数不同的数字个数,根据上面的分析,有 d p [ i ] = d p [ i − 1 ] + ? ? dp[i]=dp[i-1]+?? dp[i]=dp[i1]+??,问号部分就是增加的那部分中各个位数不相同的数字个数,我们拿 n = 3 n=3 n=3来举例,在增加的 [ 100 , 999 ] [100,999] [100,999]中,我们可以把它分成两部分,把前两位看作单独的数字,那也就是 [ 10 , 99 ] [10,99] [10,99],我们会发现这是 n = 2 n=2 n=2时照比 n = 1 n=1 n=1时增加的数字,个位可以取值的个数是 [ 0 , 9 ] [0, 9] [0,9]共10个数字,还需要减去前两位出现过的,也就是 10 − 2 = 8 10-2=8 102=8。这二者相乘便是 n = 3 n=3 n=3时增加的 [ 100 , 999 ] [100,999] [100,999]中各个位数不相同的数字个数。

d p [ i ] = d p [ i − 1 ] + ( 10 − ( i − 1 ) ) ∗ ( d p [ i − 1 ] − d p [ i − 2 ] ) dp[i] = dp[i-1] + (10-(i-1))*(dp[i-1]-dp[i-2]) dp[i]=dp[i1]+(10(i1))(dp[i1]dp[i2])

class Solution:
    def countNumbersWithUniqueDigits(self, n: int) -> int:
        if n == 0:
            return 1
        dp = [0]*(n+1)
        dp[0], dp[1] = 1, 10
        for i in range(2, n+1):
            dp[i] = dp[i-1] + (10-(i-1))*(dp[i-1]-dp[i-2])
        return dp[n]

同时可以优化内存

class Solution:
    def countNumbersWithUniqueDigits(self, n: int) -> int:
        if n == 0:
            return 1
        a, b = 1, 10
        for i in range(2, n+1):
            a, b = b, b + (b-a)*(10-(i-1))
        return b

你可能感兴趣的:(Leetcode,leetcode,算法,动态规划)