0%

357. 统计各位数字都不同的数字个数

357.统计各位数字都不同的数字个数

题目描述:

给你一个整数 n ,统计并返回各位数字都不同的数字 x 的个数,其中 $0 \le x \lt 10^n$ 。

数据范围:

$0\le n \le 8$

题解:

和上一题完全一样,就是上下界变了。

这个包括了 $0$ ,因此可以将 return !isLead 改为 return 1,或者直接在答案后面加一。由于上界变成严格小于了,那么可以直接使用 $10^n - 1$ 作为上界。

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
auto optimize_cpp_stdio = []()
{
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cout.tie(nullptr);
return 0;
}();
class Solution
{
public:
const static int maxn = 1e5 + 10;
const static int maxm = 1e5 + 10;
const int INF = 0x3f3f3f3f;
string s;
int len;
int dp[10][1 << 10];
int dfs(int step, int mask, bool isLimit, bool isLead)
{
if (step == len)
return 1;
if (!isLimit && !isLead && dp[step][mask] != -1)
return dp[step][mask];
int ans = 0;
if (isLead)
ans += dfs(step + 1, mask, false, true);
int up = isLimit ? s[step] - '0' : 9;
for (int i = isLead; i <= up; ++i)
{
if ((mask >> i) & 1)
continue;
ans += dfs(step + 1, mask | (1 << i), isLimit && i == up, false);
}
if (!isLimit && !isLead)
dp[step][mask] = ans;
return ans;
}
int countNumbersWithUniqueDigits(int n)
{
s = to_string((int)pow(10, n) - 1);
len = s.length();
memset(dp, -1, sizeof(dp));
return dfs(0, 0, true, true);
}
};