题目:
Given a non-negative integer n, count all numbers with unique digits, x, where 0 ≤ x < 10n.
Example:
Input: 2
Output: 91
Explanation: The answer should be the total numbers in the range of 0 ≤ x < 100,
excluding 11,22,33,44,55,66,77,88,99
代码:
方法一——超时:
class Solution {
public:
int helper(string x,int n) {
if (x != "" && x[0] == '0') return 0;
if (x.length()>n)return 0;
int res = 1;
for (int i = 0; i <= 9; i++) {
string tempi = to_string(i);
if (x.find(tempi) == string::npos) {
char c = '0' + i;
x.push_back(c);
res+=helper(x, n);
x.pop_back();
}
}
return res;
}
int countNumbersWithUniqueDigits(int n) {
return helper("",n);
}
};
方法二——根据公式:
class Solution {
public:
int countNumbersWithUniqueDigits(int n) {
if (n == 0) return 1;
int res = 0;
for (int i = 1; i <= n; ++i) {
res += count(i);
}
return res;
}
int count(int k) {
if (k < 1) return 0;
if (k == 1) return 10;
int res = 1;
for (int i = 9; i >= (11 - k); --i) {
res *= i;
}
return res * 9;
}
};
运用数学知识
方法三——使用位操作标记个数有没有被占用:
class Solution {
public:
int countNumbersWithUniqueDigits(int n) {
int res = 1, max = pow(10, n), used = 0;
for (int i = 1; i < 10; ++i) {
used |= (1 << i);
res += search(i, max, used);
used &= ~(1 << i);
}
return res;
}
int search(int pre, int max, int used) {
int res = 0;
if (pre < max) ++res;
else return res;
for (int i = 0; i < 10; ++i) {
if (!(used & (1 << i))) {
used |= (1 << i);
int cur = 10 * pre + i;
res += search(cur, max, used);
used &= ~(1 << i);
}
}
return res;
}
};