leetcode 357. 计算各个位数不同的数字个数(DFS,回溯,数学)

题目链接

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

题意:

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

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

思路

  • 法1:DFS+回溯
    前导0单独处理,其余位置按0~9顺序每次插入,用一个数组vis[10]记录已经用过的数字

  • 法2:数学
    设f[i]表示i位数的有效数字,比如f[1]=10,f[2]=9*9,f[3]=9*9*8,以此类推,f[i]=f[10](i>10),10个以上的数字必定重复
    最后结果就是f[1]+...+f[n](n<=10)或者f[1]+...+f[10]
    特判:n=0时,f[0]=1

class Solution {
public:
    //法2: 
    int countNumbersWithUniqueDigits(int n){
        if(n==0) return 1;

        vector<int> f(10,0);
        f[1]=10;
        f[2]=9*9;
        for(int k=3;k<=10 && k<=n;k++){
            f[k]=f[k-1]*(10-k+1);
        }

        int ans=0;
        for(int i=1;i<=n&& i<=10;i++) ans+=f[i];

        return ans;
    }

    //法1 :注意前导0
    // int dfs(int n,vector<int> vis,int d){
    //     if(n==d) return 1;
    //     int ans=1;//前导0的情况
    //     for(int i=(d==0?1:0);i<=9;i++){
    //         if(vis[i]) continue;
    //         vis[i]=1;
    //         ans+=dfs(n,vis,d+1);
    //         vis[i]=0;
    //     }
    //     return ans;
    // }
    // int countNumbersWithUniqueDigits(int n) {
    //     if(n>=10) n=10;
    //     vector<int> vis(10,0);

    //     return dfs(n,vis,0);
    //     // if(n>1) ans+=1;

    //     // dfs(0,n);
    //     // return ans;
    // }
};
posted @ 2020-11-22 10:42  xzhws  阅读(127)  评论(0编辑  收藏  举报