一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第11天,点击查看活动详情。
每日刷题 2021.04.11
- leetcode原题链接:leetcode-cn.com/problems/co…
- 难度:中等
- 方法:数学题
题目
- 给你一个整数
n,统计并返回各位数字都不同的数字x的个数,其中0 <= x < 10^n。
示例
- 示例1
输入: n = 2
输出: 91
解释: 答案应为除去 11、22、33、44、55、66、77、88、99 外,在 0 ≤ x < 100 范围内的所有数字。
- 示例2
输入: n = 0
输出: 1
提示
0 <= n <= 8
解题思路
分析
- 数学知识的运用:首先对于每个数的第一位来说都不能为
0,因为数字是不存在前导0的。 - 根据题意可知:最小的
n = 0,最大的n = 8,也就是说最大的数据范围为[0, 10 ^ 8),即最大的数求八位数不同的x的个数。 - 题目中要求:求区间
[0, 10 ^ n)之内的数, 题目中是开区间,那么我们就可以考虑到将[0, 10 ^ 1)、[10 ^ 1, 10 ^ 2)、[10 ^ 2, 10 ^ 3)....、[10 ^ (n - 1), 10 ^ n)各个区间中各位数字都不相同的数字加起来之和。
解题
- 那么就可以将一个大的区间的问题,分解成几个小的区间的问题。记区间
[0, 10 ^ n)区间中,各位数字不相同的个数为res。 - 对于
n = 0时,区间[0, 10 ^ 0 = 1),此时区间内只存在一个数1,其就是各位数字不相同的数,因此需要预判下n = 0时,返回1 - 对于
n = 1时,区间[1, 10 ^ 1),此时区间内存在的数为0,1,2,3,4,5,6,7,8,9,均为各位数字不相同的数,共有10个。 - 对于
n = 2时,区间[10 ^ 1, 10 ^ 2),区间内的数均为二位数;- 二位数的第一个位置,存在
10 - 1 = 9种情况(为什么不是10种(0,1,2,3,4,5,6,7,8,9)呢?因为首字母不能为0); - 二位数的第二个位置,存在
10 - 1 = 9种情况,因为第二个可以为0,但是不能与第一位重复。
- 二位数的第一个位置,存在
- 对于
n = 3时,区间[10 ^ 2, 10 ^ 3),区间内的数均为三位数;- 三位数的第一个位置,存在
10 - 1 = 9种情况(为什么不是10种(0,1,2,3,4,5,6,7,8,9)呢?因为首字母不能为0); - 三位数的第二个位置,存在
10 - 1 = 9种情况,因为第二个可以为0,但是不能与第一位重复。 - 三位数的第三个位置,存在
10 - 1 - 1 = 8种情况,因为第三个位置可以为0,但是不能与第一和第二位重复,因此需要减去这两种情况
- 三位数的第一个位置,存在
- 对于
n = 4,5,6,7,8时,发现与上述的规律相同。 - 最后将所有的区间各位不相同的数的个数相加即可,得到答案。
排列组合
AC代码
var countNumbersWithUniqueDigits = function(n) {
if(n == 0) return 1;
// 乘法的运算
let res = 10,multi = 9;
if(n == 1) return res;
// 9 * 9 \ 9 * 9 * 8 \ 9 * 9 * 8 * 7 \ 9 * 9 * 8 * 7 * 6
for(let i = 2; i <= n; i++) {
multi = multi * (10 - i + 1);
res += multi;
}
return res;
};
总结
- 利用乘法原理,每位数可选的数值个数相乘即是长度为
n的数的可能方案数cur,而所有长度[1, n]的方案数累加即是答案。