[ 数学题 ]357. 统计各位数字都不同的数字个数

307 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第11天,点击查看活动详情

每日刷题 2021.04.11

题目

  • 给你一个整数 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]的方案数累加即是答案。