Skip to content

Commit 0e417ef

Browse files
committed
modify code
1 parent 308e2cd commit 0e417ef

10 files changed

+578
-0
lines changed
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package class084;
2+
3+
// 统计各位数字都不同的数字个数
4+
// 给你一个整数n,代表十进制数字最多有n位
5+
// 如果某个数字,每一位都不同,那么这个数字叫做有效数字
6+
// 返回有效数字的个数,不统计负数范围
7+
// 测试链接 : https://leetcode.cn/problems/count-numbers-with-unique-digits/
8+
public class Code01_CountNumbersWithUniqueDigits {
9+
10+
public static int countNumbersWithUniqueDigits(int n) {
11+
if (n == 0) {
12+
return 1;
13+
}
14+
int ans = 10;
15+
for (int s = 9, i = 9, k = 2; k <= n; i--, k++) {
16+
s *= i;
17+
ans += s;
18+
}
19+
return ans;
20+
}
21+
22+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package class084;
2+
3+
// 至少有1位重复的数字
4+
// 给定正整数n
5+
// 返回在[1, n]范围内具有至少1位重复数字的正整数的个数
6+
// 测试链接 : https://leetcode.cn/problems/numbers-with-repeated-digits/
7+
public class Code02_NumbersWithRepeatedDigits {
8+
9+
public static int numDupDigitsAtMostN(int n) {
10+
if (n <= 10) {
11+
return 0;
12+
}
13+
int len = 1;
14+
int offset = 1;
15+
int tmp = n / 10;
16+
while (tmp > 0) {
17+
len++;
18+
offset *= 10;
19+
tmp /= 10;
20+
}
21+
int noRepeat = 0;
22+
for (int i = 1, cnt = 9, cur = 9; i < len; i++) {
23+
if (i == 1) {
24+
noRepeat += 10;
25+
} else {
26+
cnt *= cur--;
27+
noRepeat += cnt;
28+
}
29+
}
30+
int[] cnt = new int[len];
31+
cnt[0] = 1;
32+
for (int i = 1, ans = 1, base = 10 - len + 1; i < len; i++, base++) {
33+
ans *= base;
34+
cnt[i] = ans;
35+
}
36+
int status = 0b1111111111;
37+
noRepeat += ((n / offset) - 1) * cnt[len - 1];
38+
noRepeat += f(cnt, len - 1, offset / 10, status ^ (1 << (n / offset)), n);
39+
return n + 1 - noRepeat;
40+
}
41+
42+
public static int f(int[] cnt, int len, int offset, int status, int n) {
43+
if (len == 0) {
44+
return 1;
45+
}
46+
int ans = 0;
47+
int first = (n / offset) % 10;
48+
for (int cur = 0; cur < first; cur++) {
49+
if ((status & (1 << cur)) != 0) {
50+
ans += cnt[len - 1];
51+
}
52+
}
53+
if ((status & (1 << first)) != 0) {
54+
ans += f(cnt, len - 1, offset / 10, status ^ (1 << first), n);
55+
}
56+
return ans;
57+
}
58+
59+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package class084;
2+
3+
// 最大为N的数字组合
4+
// 给定一个按 非递减顺序 排列的数字数组 digits
5+
// 你可以用任意次数 digits[i] 来写的数字
6+
// 例如,如果 digits = ['1','3','5']
7+
// 我们可以写数字,如 '13', '551', 和 '1351315'
8+
// 返回 可以生成的小于或等于给定整数 n 的正整数的个数
9+
// 测试链接 : https://leetcode.cn/problems/numbers-at-most-n-given-digit-set/
10+
public class Code03_NumbersAtMostGivenDigitSet {
11+
12+
public static int atMostNGivenDigitSet(String[] strs, int number) {
13+
int m = strs.length;
14+
int[] digits = new int[m];
15+
for (int i = 0; i < m; i++) {
16+
digits[i] = Integer.valueOf(strs[i]);
17+
}
18+
int tmp = number / 10;
19+
int len = 1;
20+
int offset = 1;
21+
while (tmp > 0) {
22+
tmp /= 10;
23+
len++;
24+
offset *= 10;
25+
}
26+
int[] cnt = new int[len];
27+
cnt[0] = 1;
28+
int ans = 0;
29+
for (int prepare = m, i = 1; i < len; i++, prepare *= m) {
30+
cnt[i] = prepare;
31+
ans += prepare;
32+
}
33+
return ans + f(digits, cnt, number, offset, len);
34+
}
35+
36+
public static int f(int[] digits, int[] cnt, int number, int offset, int len) {
37+
if (len == 0) {
38+
return 1;
39+
}
40+
int cur = (number / offset) % 10;
41+
int ans = 0;
42+
for (int i = 0; i < digits.length; i++) {
43+
if (digits[i] < cur) {
44+
ans += cnt[len - 1];
45+
} else if (digits[i] == cur) {
46+
ans += f(digits, cnt, number, offset / 10, len - 1);
47+
} else {
48+
break;
49+
}
50+
}
51+
return ans;
52+
}
53+
54+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package class084;
2+
3+
// 统计特殊整数
4+
// 如果一个正整数每一个数位都是 互不相同 的,我们称它是 特殊整数
5+
// 给你一个正整数n,请你返回区间 [1, n] 之间特殊整数的数目
6+
// 测试链接 : https://leetcode.cn/problems/count-special-integers/
7+
public class Code04_CountSpecialIntegers {
8+
9+
public static int[] offset = {
10+
0, // 0
11+
1, // 1
12+
10, // 2
13+
100, // 3
14+
1000, // 4
15+
10000, // 5
16+
100000, // 6
17+
1000000, // 7
18+
10000000, // 8
19+
100000000, // 9
20+
1000000000 // 10
21+
};
22+
23+
public static int countSpecialNumbers(int n) {
24+
int len = len(n);
25+
int ans = 0;
26+
for (int i = 1; i < len; i++) {
27+
ans += all(i);
28+
}
29+
int firstNumber = n / offset[len];
30+
ans += (firstNumber - 1) * small(len - 1, 9);
31+
ans += f(n, len, len - 1, 1 << firstNumber);
32+
return ans;
33+
}
34+
35+
public static int len(int n) {
36+
int ans = 0;
37+
while (n != 0) {
38+
ans++;
39+
n /= 10;
40+
}
41+
return ans;
42+
}
43+
44+
public static int all(int bits) {
45+
int ans = 9;
46+
int cur = 9;
47+
while (--bits != 0) {
48+
ans *= cur--;
49+
}
50+
return ans;
51+
}
52+
53+
public static int small(int bits, int candidates) {
54+
int ans = 1;
55+
for (int i = 0; i < bits; i++, candidates--) {
56+
ans *= candidates;
57+
}
58+
return ans;
59+
}
60+
61+
public static int f(int num, int len, int rest, int status) {
62+
if (rest == 0) {
63+
return 1;
64+
}
65+
int cur = (num / offset[rest]) % 10;
66+
int cnt = 0;
67+
for (int i = 0; i < cur; i++) {
68+
if ((status & (1 << i)) == 0) {
69+
cnt++;
70+
}
71+
}
72+
int ans = cnt * small(rest - 1, 9 - (len - rest));
73+
if ((status & (1 << cur)) == 0) {
74+
ans += f(num, len, rest - 1, status | (1 << cur));
75+
}
76+
return ans;
77+
}
78+
79+
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
package class085;
2+
3+
// 统计整数数目
4+
// 给你两个数字字符串 num1 和 num2 ,以及两个整数max_sum和min_sum
5+
// 如果一个整数 x 满足以下条件,我们称它是一个好整数
6+
// num1 <= x <= num2
7+
// min_sum <= digit_sum(x) <= max_sum
8+
// 请你返回好整数的数目
9+
// 答案可能很大请返回答案对10^9 + 7 取余后的结果
10+
// 注意,digit_sum(x)表示x各位数字之和
11+
// 测试链接 : https://leetcode.cn/problems/count-of-integers/
12+
public class Code01_CountOfIntegers {
13+
14+
public static int MOD = 1000000007;
15+
16+
public static int MAXN = 23;
17+
18+
public static int MAXM = 401;
19+
20+
public static int[][][] dp = new int[MAXN][MAXM][2];
21+
22+
public static void build() {
23+
for (int i = 0; i < n; i++) {
24+
for (int j = 0; j <= m; j++) {
25+
dp[i][j][0] = -1;
26+
dp[i][j][1] = -1;
27+
}
28+
}
29+
}
30+
31+
public static char[] num;
32+
33+
public static int n, m;
34+
35+
public static int count(String num1, String num2, int min_sum, int max_sum) {
36+
num = num2.toCharArray();
37+
n = num2.length();
38+
m = max_sum;
39+
build();
40+
int ans = f(0, 0, 0, min_sum, max_sum);
41+
num = num1.toCharArray();
42+
n = num1.length();
43+
build();
44+
ans = (ans - f(0, 0, 0, min_sum, max_sum) + MOD) % MOD;
45+
if (check(min_sum, max_sum)) {
46+
ans = (ans + 1) % MOD;
47+
}
48+
return ans;
49+
}
50+
51+
public static int f(int i, int sum, int less, int min, int max) {
52+
if (sum > max) {
53+
return 0;
54+
}
55+
if (sum + (n - i) * 9 < min) {
56+
return 0;
57+
}
58+
if (i == n) {
59+
return 1;
60+
}
61+
if (dp[i][sum][less] != -1) {
62+
return dp[i][sum][less];
63+
}
64+
int cur = num[i] - '0';
65+
int ans = 0;
66+
if (less == 0) {
67+
for (int pick = 0; pick < cur; pick++) {
68+
ans = (ans + f(i + 1, sum + pick, 1, min, max)) % MOD;
69+
}
70+
ans = (ans + f(i + 1, sum + cur, 0, min, max)) % MOD;
71+
} else {
72+
for (int pick = 0; pick <= 9; pick++) {
73+
ans = (ans + f(i + 1, sum + pick, 1, min, max)) % MOD;
74+
}
75+
}
76+
dp[i][sum][less] = ans;
77+
return ans;
78+
}
79+
80+
public static boolean check(int min, int max) {
81+
int sum = 0;
82+
for (char cha : num) {
83+
sum += cha - '0';
84+
}
85+
return sum >= min && sum <= max;
86+
}
87+
88+
}

0 commit comments

Comments
 (0)