题目描述
Given a non-negative integer n, count all numbers with unique digits, x, where 0 ≤ x < 10n.
Example:
Given n = 2, return 91. (The answer should be the total numbers in the range of 0 ≤ x < 100, excluding [11,22,33,44,55,66,77,88,99]
)
解题思路
1)怎么计算每个位上数字不同的整数的个数?(看下图,一切尽在不言中)
(注意最高位不可能为 0)
2)n = 3时,要求出 10以内 、 100 以内 、 1000以内的数字不同整数个数。于是,用一个数组re[i]表示10^i 的个数,不难得出状态转移方程
re[i] = re[i - 1]+ (10^i-1 ~10^i 间 不同数字整数个数);
综上,我得出两个解法代码
1)多用一个数组表示 9*8*7*6……,这是根据10^i-1 ~10^i 与 10^i-2 ~10^i-1之间的关系得到的,代码如下:
class Solution {
public:
int countNumbersWithUniqueDigits(int n) {
if(n == 0)
return 1;
vector<int> re(n, 0);
vector<int> retmp(n, 0);
re[0] = 10;
retmp[0] = 10;
re[1] = 91;
retmp[1] = 81;
int count = 8;
for (int i = 2; i < n; i++) {
retmp[i] = retmp[i - 1] * count;
re[i] = re[i - 1] + (retmp[i-1]*count);
count--;
}
return re[re.size() - 1];
}
};
2) 10^i-1 ~10^i 的整数个数用一个while循环计算
class Solution {
public:
int countNumbersWithUniqueDigits(int n) {
if(n == 0)
return 1;
vector<int> re(n, 0);
re[0] = 10;
for (int i = 1; i < n; i++) {
int tmp = i;
int now1 = 9;
int now2 = 9;
while (tmp--) {
now2 *= now1;
now1--;
}
re[i] = re[i - 1] + now2;
}
return re[re.size() - 1];
}
};
感觉上应该第一种算法会优于第二种,可能是由于样例太少的缘故(其实这道题本来就不需要太多样例,n >= 10的结果都是一样的了),leetcode上第二种解法时间是0ms……