357. 统计各位数字都不同的数字个数
给你一个整数 n
,统计并返回各位数字都不同的数字 x
的个数,其中 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
解题思路
本题本质就是用不同 0-9 的数字组合成各位数字都不同的数字
-
当 n == 0 时, res = 1 只有 0
-
当 n == 1 时, res = 10 有 0 和 1 - 9 , 结果为 n == 0 和 n == 1 的和
-
当 2 <= n <= 8 时, 最高位从 0-9 里面选择不能选择 0 ,只能选 1 - 9中的一个,有9种选法;后面的位数,可以从0-9中除去最高位的一个,即9个数选一个,再后一个只能从8个选,那么将n = [0,n]的全加上即可
代码
class Solution {
public:
/*
本题本质就是用不同 0-9 的数字组合成各位数字都不同的数字
- 当 n == 0 时, res = 1 只有 0
- 当 n == 1 时, res = 10 有 0 和 1 - 9 , 结果为 n == 0 和 n == 1 的和
- 当 2 <= n <= 8 时, 最高位从 0-9 里面选择不能选择 0 ,只能选 1 - 9中的一个,有9种选法 C(9,1),
- 后面的位数,可以从0-9中除去最高位的一个,即9个数选一个,再后一个只能从8个选
- 那么将n = [0,n]的全加上即可
*/
int getNDiff(int n){
// 获取有n位数中不同的个数,n>1
// 第一位非0,可选9个,第i(i>0)个开始可选0-9除去已选的,即10-i
int ans = 9;
for(int i = 1;i<n;i++) ans*=(10-i);
return ans;
}
int countNumbersWithUniqueDigits(int n) {
if(n<2) return pow(10,n);
int ans = 10; // n = 0 1 时的数量
for(int i = 2;i<=n;i++){
ans += getNDiff(i);
}
return ans;
}
};