声明:原题目转载自LeetCode,解答部分为原创
Problem :
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]
)
Solution :
思路:这道编程题属于动态规划的题目。先举个例子,{1,12,123,1234......} 这类数的各位上的数值均不同,而{11,22,33,44........}各位上的数值均相同。题意是求解各位上的值不同的数的个数,当 n == 0 时,在 [ 0, 1)范围内有且仅有一个数满足条件,即 { 0 },当 n == 1 时,在 [ 0, 10 )范围内有10个数满足条件,当 n >= 2 时,记 f( n )为 [ 0, 10^n )范围内满足条件的数值个数,记 g( k ) 为 k位数中满足条件的数值个数, 则 f(n) = g(1) + g(2) + g(3) + ... +g(n) = f(n - 1) + g(n),而 g(n) 属于组合问题, g(n) = 9 * 9 * 8 * 7 *...... * (11 - n),第一个“9”代表最高位上可选择的数为“ 1 ~ 9”九个,0 不可选,第二个“9”代表第二位上可选择的数为“0 ~ 9”中除去高位所选的其他九个数,依次类推,第 n 位上可选的数有 ( 11 - n ) 个。
代码如下:
#include<iostream>
using namespace std;
/*
class Solution {
public:
int countNumbersWithUniqueDigits(int n) {
if(n == 0)
return 1;
int ret = 0;
for(int i = 0 ; i < n ; i ++)
{
ret += num_of_n_bits(i + 1);
}
return ret;
}
int num_of_n_bits(int n) {
if(n == 1)
return 10;
int ret = 9;
for(int i = 0 ; i < n - 1; i ++)
{
ret *= 9 - i;
}
return ret;
}
};
*/
class Solution {
public:
int countNumbersWithUniqueDigits(int n) {
if(n == 0)
return 1;
if(n == 1)
return 10;
int ret = 10;
int last_state = 9;
for(int i = 1 ; i < n ; i ++)
{
last_state *= (10 - i);
ret += last_state;
}
return ret;
}
};
int main()
{
Solution text;
cout << text.countNumbersWithUniqueDigits(1) << endl;
cout << text.countNumbersWithUniqueDigits(2) << endl;
cout << text.countNumbersWithUniqueDigits(3) << endl;
cout << text.countNumbersWithUniqueDigits(4) << endl;
return 0;
}