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

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

示例:

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

解题思路:

排列组合问题。题目分析可知,n也就是数字的位数。首先分析一个n位数中不同数字的个数val[n]。

  1. 除了n=1之外,首位数字不可能为0,否则该数实质上是一个n-1位数。如果n=1,直接返回10即可。n=0,直接返回1。
  2. 当n>10时,必然有重复数字,因为阿拉伯数字也就10个。
  3. val[n]=9*(9)*(9-1)*(9-2)*...*(9-(n-2))。高中排列组合的知识。
  4. 没有必要对每一个val[n]都计算这个连乘式子,因为存在递推关系va[n]=val[n-1]*(9-(n-2)),算法可以优化到只算O(n)个乘法运算。
  5. 最后扫描一趟,无需额外空间,即可算出前n个数的和,即为本题所需答案。

Leetcode:357.计算各个位数不同数字的个数_第1张图片

C++代码
class Solution {
public:
    int countNumbersWithUniqueDigits(int n) {
        if (n == 0) return 1;
        if (n > 10) return countNumbersWithUniqueDigits(10);
        vector dp(n + 1, 1);
        dp[1] = 10;
        if (n == 1) return dp[1];
        int temp = 9, sgn = 9,i;
        for (i = 2; i <= n; i++) {
            dp[i] = temp*sgn;
            temp = dp[i];
            sgn--;
        }
        for (i = 2; i <= n; i++) {
            dp[i] += dp[i - 1];
        }
        return dp.back();
    }
};

 

你可能感兴趣的:(Leetcode,C,Leetcode,C,计算各个位数不同数字的个数)