题目
357.统计各位数字都不同的数字个数
题目大意
给你一个整数 n
,统计并返回各位数字都不同的数字 x
的个数,其中
0
<
=
x
<
1
0
n
0 <= x < 10^n
0<=x<10n 。
样例
示例 1:
输入:n = 2
输出:91
解释:答案应为除去 11、22、33、44、55、66、77、88、99 外,在 0 ≤ x < 100 范围内的所有数字。
示例 2:
输入:n = 0
输出:1
数据规模
提示:
0 <= n <= 8
思路
这是一个排列组合问题,设总方案数为ans
,当前选到第
i
i
i轮之后产生的数字有
t
o
t
tot
tot个,首先先考虑普适性情况:
n
>
1
n>1
n>1,那么左边第一位数字可以选择
0
∼
9
0\sim9
0∼9,如果选择了
0
0
0那么之后就不能再选数字了,所以可以继续往后填充数字的只有
1
∼
9
1\sim9
1∼9。假如第一位选择了
1
∼
9
1\sim9
1∼9中的某个数字,假设它是
x
0
x_0
x0,那么第二位可以选择
0
∼
9
0\sim9
0∼9中除
x
0
x_0
x0的任意数字,假设它是
x
1
x_1
x1,那么第三位可以选择
0
∼
9
0\sim9
0∼9中除
x
0
,
x
1
x_0,x_1
x0,x1的任意数字,以此类推即可。
更一般地,含有 d d d位数的各位数字都不同的数字 x x x的个数可以由公式 9 × A 9 d − 1 9 \times A_9^{d-1} 9×A9d−1计算。再加上含有小于 d d d位数的各位数字都不同的数字 x x x的个数,即可得到答案。
特殊的, n = 0 n=0 n=0时答案为 1 1 1。
代码
// short int long float double bool char string void
// array vector stack queue auto const operator
// class public private static friend extern
// sizeof new delete return cout cin memset malloc
// relloc size length memset malloc relloc size length
// for while if else switch case continue break system
// endl reverse sort swap substr begin end iterator
// namespace include define NULL nullptr exit equals
// index col row arr err left right ans res vec que sta
// state flag ch str max min default charray std
// maxn minn INT_MAX INT_MIN push_back insert
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int>PII;
typedef pair<int, string>PIS;
const int maxn=3e4+50;//注意修改大小
long long read(){long long x=0,f=1;char c=getchar();while(!isdigit(c)){if(c=='-') f=-1;c=getchar();}while(isdigit(c)){x=x*10+c-'0';c=getchar();}return x*f;}
ll qpow(ll x,ll q,ll Mod){ll ans=1;while(q){if(q&1)ans=ans*x%Mod;q>>=1;x=(x*x)%Mod;}return ans%Mod;}
class Solution {
public:
int countNumbersWithUniqueDigits(int n) {
if(n==0)return 1;
ll ans=10,tot=9;
for(int i=0;i<n-1;i++){
tot=tot*(9-i);
ans+=tot;
}
return ans;
}
};