Skip to content

Commit 767a71d

Browse files
authored
feat: add solutions to lc problem: No.2376 (#3535)
No.2376.Count Special Integers
1 parent de4ed82 commit 767a71d

File tree

11 files changed

+408
-824
lines changed

11 files changed

+408
-824
lines changed

solution/2300-2399/2376.Count Special Integers/README.md

Lines changed: 136 additions & 285 deletions
Large diffs are not rendered by default.

solution/2300-2399/2376.Count Special Integers/README_EN.md

Lines changed: 139 additions & 263 deletions
Large diffs are not rendered by default.
Lines changed: 27 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,34 @@
11
class Solution {
22
public:
33
int countSpecialNumbers(int n) {
4-
int ans = 0;
5-
vector<int> digits;
6-
while (n) {
7-
digits.push_back(n % 10);
8-
n /= 10;
9-
}
10-
int m = digits.size();
11-
vector<bool> vis(10);
12-
for (int i = 1; i < m; ++i) {
13-
ans += 9 * A(9, i - 1);
14-
}
15-
for (int i = m - 1; ~i; --i) {
16-
int v = digits[i];
17-
for (int j = i == m - 1 ? 1 : 0; j < v; ++j) {
18-
if (!vis[j]) {
19-
ans += A(10 - (m - i), i);
20-
}
4+
string s = to_string(n);
5+
int m = s.size();
6+
int f[m][1 << 10];
7+
memset(f, -1, sizeof(f));
8+
auto dfs = [&](auto&& dfs, int i, int mask, bool lead, bool limit) -> int {
9+
if (i >= m) {
10+
return lead ^ 1;
2111
}
22-
if (vis[v]) {
23-
break;
12+
if (!limit && !lead && f[i][mask] != -1) {
13+
return f[i][mask];
2414
}
25-
vis[v] = true;
26-
if (i == 0) {
27-
++ans;
15+
int up = limit ? s[i] - '0' : 9;
16+
int ans = 0;
17+
for (int j = 0; j <= up; ++j) {
18+
if (mask >> j & 1) {
19+
continue;
20+
}
21+
if (lead && j == 0) {
22+
ans += dfs(dfs, i + 1, mask, true, limit && j == up);
23+
} else {
24+
ans += dfs(dfs, i + 1, mask | (1 << j), false, limit && j == up);
25+
}
2826
}
29-
}
30-
return ans;
31-
}
32-
33-
int A(int m, int n) {
34-
return n == 0 ? 1 : A(m, n - 1) * (m - n + 1);
27+
if (!limit && !lead) {
28+
f[i][mask] = ans;
29+
}
30+
return ans;
31+
};
32+
return dfs(dfs, 0, 0, true, true);
3533
}
36-
};
34+
};

solution/2300-2399/2376.Count Special Integers/Solution.go

Lines changed: 34 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,42 @@
11
func countSpecialNumbers(n int) int {
2-
digits := []int{}
3-
for n != 0 {
4-
digits = append(digits, n%10)
5-
n /= 10
6-
}
7-
m := len(digits)
8-
vis := make([]bool, 10)
9-
ans := 0
10-
for i := 1; i < m; i++ {
11-
ans += 9 * A(9, i-1)
12-
}
13-
for i := m - 1; i >= 0; i-- {
14-
v := digits[i]
15-
j := 0
16-
if i == m-1 {
17-
j = 1
2+
s := strconv.Itoa(n)
3+
m := len(s)
4+
f := make([][1 << 10]int, m+1)
5+
for i := range f {
6+
for j := range f[i] {
7+
f[i][j] = -1
188
}
19-
for ; j < v; j++ {
20-
if !vis[j] {
21-
ans += A(10-(m-i), i)
9+
}
10+
var dfs func(int, int, bool, bool) int
11+
dfs = func(i, mask int, lead, limit bool) int {
12+
if i >= m {
13+
if lead {
14+
return 0
2215
}
16+
return 1
17+
}
18+
if !limit && !lead && f[i][mask] != -1 {
19+
return f[i][mask]
2320
}
24-
if vis[v] {
25-
break
21+
up := 9
22+
if limit {
23+
up = int(s[i] - '0')
2624
}
27-
vis[v] = true
28-
if i == 0 {
29-
ans++
25+
ans := 0
26+
for j := 0; j <= up; j++ {
27+
if mask>>j&1 == 1 {
28+
continue
29+
}
30+
if lead && j == 0 {
31+
ans += dfs(i+1, mask, true, limit && j == up)
32+
} else {
33+
ans += dfs(i+1, mask|1<<j, false, limit && j == up)
34+
}
3035
}
36+
if !limit && !lead {
37+
f[i][mask] = ans
38+
}
39+
return ans
3140
}
32-
return ans
41+
return dfs(0, 0, true, true)
3342
}
34-
35-
func A(m, n int) int {
36-
if n == 0 {
37-
return 1
38-
}
39-
return A(m, n-1) * (m - n + 1)
40-
}
Lines changed: 26 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,35 @@
11
class Solution {
2+
private char[] s;
3+
private Integer[][] f;
4+
25
public int countSpecialNumbers(int n) {
3-
List<Integer> digits = new ArrayList<>();
4-
while (n != 0) {
5-
digits.add(n % 10);
6-
n /= 10;
6+
s = String.valueOf(n).toCharArray();
7+
f = new Integer[s.length][1 << 10];
8+
return dfs(0, 0, true, true);
9+
}
10+
11+
private int dfs(int i, int mask, boolean lead, boolean limit) {
12+
if (i >= s.length) {
13+
return lead ? 0 : 1;
714
}
8-
int m = digits.size();
9-
int ans = 0;
10-
for (int i = 1; i < m; ++i) {
11-
ans += 9 * A(9, i - 1);
15+
if (!limit && !lead && f[i][mask] != null) {
16+
return f[i][mask];
1217
}
13-
boolean[] vis = new boolean[10];
14-
for (int i = m - 1; i >= 0; --i) {
15-
int v = digits.get(i);
16-
for (int j = i == m - 1 ? 1 : 0; j < v; ++j) {
17-
if (vis[j]) {
18-
continue;
19-
}
20-
ans += A(10 - (m - i), i);
21-
}
22-
if (vis[v]) {
23-
break;
18+
int up = limit ? s[i] - '0' : 9;
19+
int ans = 0;
20+
for (int j = 0; j <= up; ++j) {
21+
if ((mask >> j & 1) == 1) {
22+
continue;
2423
}
25-
vis[v] = true;
26-
if (i == 0) {
27-
++ans;
24+
if (lead && j == 0) {
25+
ans += dfs(i + 1, mask, true, limit && j == up);
26+
} else {
27+
ans += dfs(i + 1, mask | (1 << j), false, limit && j == up);
2828
}
2929
}
30+
if (!limit && !lead) {
31+
f[i][mask] = ans;
32+
}
3033
return ans;
3134
}
32-
33-
private int A(int m, int n) {
34-
return n == 0 ? 1 : A(m, n - 1) * (m - n + 1);
35-
}
36-
}
35+
}
Lines changed: 16 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,19 @@
11
class Solution:
22
def countSpecialNumbers(self, n: int) -> int:
3-
def A(m, n):
4-
return 1 if n == 0 else A(m, n - 1) * (m - n + 1)
3+
@cache
4+
def dfs(i: int, mask: int, lead: bool, limit: bool) -> int:
5+
if i >= len(s):
6+
return int(lead ^ 1)
7+
up = int(s[i]) if limit else 9
8+
ans = 0
9+
for j in range(up + 1):
10+
if mask >> j & 1:
11+
continue
12+
if lead and j == 0:
13+
ans += dfs(i + 1, mask, True, limit and j == up)
14+
else:
15+
ans += dfs(i + 1, mask | 1 << j, False, limit and j == up)
16+
return ans
517

6-
vis = [False] * 10
7-
ans = 0
8-
digits = [int(c) for c in str(n)[::-1]]
9-
m = len(digits)
10-
for i in range(1, m):
11-
ans += 9 * A(9, i - 1)
12-
for i in range(m - 1, -1, -1):
13-
v = digits[i]
14-
j = 1 if i == m - 1 else 0
15-
while j < v:
16-
if not vis[j]:
17-
ans += A(10 - (m - i), i)
18-
j += 1
19-
if vis[v]:
20-
break
21-
vis[v] = True
22-
if i == 0:
23-
ans += 1
24-
return ans
18+
s = str(n)
19+
return dfs(0, 0, True, True)
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
function countSpecialNumbers(n: number): number {
2+
const s = n.toString();
3+
const m = s.length;
4+
const f: number[][] = Array.from({ length: m }, () => Array(1 << 10).fill(-1));
5+
const dfs = (i: number, mask: number, lead: boolean, limit: boolean): number => {
6+
if (i >= m) {
7+
return lead ? 0 : 1;
8+
}
9+
if (!limit && !lead && f[i][mask] !== -1) {
10+
return f[i][mask];
11+
}
12+
const up = limit ? +s[i] : 9;
13+
let ans = 0;
14+
for (let j = 0; j <= up; ++j) {
15+
if ((mask >> j) & 1) {
16+
continue;
17+
}
18+
if (lead && j === 0) {
19+
ans += dfs(i + 1, mask, true, limit && j === up);
20+
} else {
21+
ans += dfs(i + 1, mask | (1 << j), false, limit && j === up);
22+
}
23+
}
24+
if (!limit && !lead) {
25+
f[i][mask] = ans;
26+
}
27+
return ans;
28+
};
29+
return dfs(0, 0, true, true);
30+
}

solution/2300-2399/2376.Count Special Integers/Solution2.cpp

Lines changed: 0 additions & 42 deletions
This file was deleted.

solution/2300-2399/2376.Count Special Integers/Solution2.go

Lines changed: 0 additions & 53 deletions
This file was deleted.

0 commit comments

Comments
 (0)