357. 统计各位数字都不同的数字个数
标签: math
, dynamic-programming
, backtracking
难度: Medium
通过率: 53.58%
原题链接: https://leetcode.com/problems/count-numbers-with-unique-digits/description/
题目描述
给定一个整数 ,返回所有不超过 的各位数字都不同的数字的个数。
解题思路
为了解决这个问题,我们需要统计位数不超过 的数字,且这些数字的每一位都不相同。
我们可以认为这是一个排列问题:我们有 个数字( 到 ),从中选择不同的数字组成数字。由于选择的数字可以不排列成满位数,因此也要考虑短位数的排列。
问题可以用动态规划来求解:
- 表示位数为 的各位数字不同的数字的个数。
- 当 时, ,因为只有数字 本身。
对于 ,自然有 个不同的数字( 到 )。即 。
当 时,比如 :
- 第一位可以选择 到 共 种可能。
- 第二位可以选择 到 中除去第一位的数字,共 种可能。
- 即 。
推广到一般的 :
- 对于第 位,可以选择的数字有 种,注意第一个数字不能为 。
- 因此 可以通过累积不同位数的数字解决:
然后累积求和所有 的 。
代码实现
- Python
- C++
- JavaScript
- Java
def countNumbersWithUniqueDigits(n):
# 如果 n 为 0,则只有数字 0 是不重复的
if n == 0:
return 1
# 初始化总计数为 10,第一个数字有 10 种可能性
total_count = 10
# 可选的数字从 9 开始,因为第一个数字不能是 0
available_numbers = 9
# 初始化动态组合的乘积
product = 9
# 从第二个数字开始计算
for i in range(2, n + 1):
product *= available_numbers
total_count += product
available_numbers -= 1
return total_count
int countNumbersWithUniqueDigits(int n) {
if (n == 0) return 1;
int total_count = 10;
int product = 9;
int available_numbers = 9;
for (int i = 2; i <= n; ++i) {
product *= available_numbers;
total_count += product;
available_numbers--;
}
return total_count;
}
function countNumbersWithUniqueDigits(n) {
if (n === 0) return 1;
let total_count = 10;
let product = 9;
let available_numbers = 9;
for (let i = 2; i <= n; i++) {
product *= available_numbers;
total_count += product;
available_numbers--;
}
return total_count;
}
public int countNumbersWithUniqueDigits(int n) {
if (n == 0) return 1;
int total_count = 10;
int product = 9;
int available_numbers = 9;
for (int i = 2; i <= n; i++) {
product *= available_numbers;
total_count += product;
available_numbers--;
}
return total_count;
}
复杂度分析
时间复杂度:
空间复杂度: