Skip to content

Commit 3e971f1

Browse files
committed
Improved task 3343
1 parent 49b8db3 commit 3e971f1

File tree

1 file changed

+57
-73
lines changed
  • src/main/java/g3301_3400/s3343_count_number_of_balanced_permutations

1 file changed

+57
-73
lines changed
Lines changed: 57 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,94 +1,78 @@
11
package g3301_3400.s3343_count_number_of_balanced_permutations;
22

3-
// #Hard #2024_11_04_Time_182_ms_(100.00%)_Space_45.6_MB_(100.00%)
4-
5-
import java.util.ArrayList;
6-
import java.util.HashMap;
7-
import java.util.List;
8-
import java.util.Map;
3+
// #Hard #2024_11_05_Time_61_ms_(97.56%)_Space_44.3_MB_(100.00%)
94

105
public class Solution {
11-
private static final long M = 1000000007;
12-
private int[] freq;
6+
private static final int M = 1000000007;
137

14-
public int countBalancedPermutations(String num) {
15-
int[] freq = new int[10];
16-
int sum = 0;
17-
for (int i = 0; i < num.length(); i++) {
18-
int v = num.charAt(i) - '0';
19-
freq[v]++;
20-
sum += v;
21-
}
22-
if (sum % 2 == 1) {
23-
return 0;
8+
public int countBalancedPermutations(String n) {
9+
int l = n.length();
10+
int ts = 0;
11+
int[] c = new int[10];
12+
for (char d : n.toCharArray()) {
13+
c[d - '0']++;
14+
ts += d - '0';
2415
}
25-
sum /= 2;
26-
this.freq = freq;
27-
int evenCount = num.length() / 2;
28-
int oddCount = num.length() - evenCount;
29-
return (int) countAll(9, evenCount, oddCount, sum, sum);
30-
}
31-
32-
private final Map<Long, Long> cache = new HashMap<>();
33-
34-
private long countAll(
35-
int idx, int evenLeftCount, int oddLeftCount, int evenLeftSum, int oddLeftSum) {
36-
if (evenLeftCount < 0 || oddLeftCount < 0 || evenLeftSum < 0 || oddLeftSum < 0) {
16+
if (ts % 2 != 0) {
3717
return 0;
3818
}
39-
if (idx == -1) {
40-
if (evenLeftCount == 0 && oddLeftCount == 0) {
41-
return 1;
42-
}
43-
return 0;
19+
int hs = ts / 2;
20+
int m = (l + 1) / 2;
21+
long[] f = new long[l + 1];
22+
f[0] = 1;
23+
for (int i = 1; i <= l; i++) {
24+
f[i] = f[i - 1] * i % M;
4425
}
45-
long key = (((long) evenLeftCount) << 48) + (((long) evenLeftSum) << 32) + idx;
46-
if (cache.containsKey(key)) {
47-
return cache.get(key);
26+
long[] invF = new long[l + 1];
27+
invF[l] = modInverse(f[l], M);
28+
for (int i = l - 1; i >= 0; i--) {
29+
invF[i] = invF[i + 1] * (i + 1) % M;
4830
}
49-
long total = 0;
50-
for (int i = 0; i <= freq[idx]; i++) {
51-
int j = freq[idx] - i;
52-
long c =
53-
countAll(
54-
idx - 1,
55-
evenLeftCount - i,
56-
oddLeftCount - j,
57-
evenLeftSum - i * idx,
58-
oddLeftSum - j * idx);
59-
if (c == 0) {
31+
long[][] dp = new long[m + 1][hs + 1];
32+
dp[0][0] = 1;
33+
for (int d = 0; d <= 9; d++) {
34+
if (c[d] == 0) {
6035
continue;
6136
}
62-
c = (c * choose(evenLeftCount, i)) % M;
63-
c = (c * choose(oddLeftCount, j)) % M;
64-
total = (total + c) % M;
37+
for (int k = m; k >= 0; k--) {
38+
for (int s = hs; s >= 0; s--) {
39+
if (dp[k][s] == 0) {
40+
continue;
41+
}
42+
for (int t = 1; t <= c[d] && k + t <= m && s + d * t <= hs; t++) {
43+
dp[k + t][s + d * t] =
44+
(dp[k + t][s + d * t] + dp[k][s] * comb(c[d], t, f, invF, M)) % M;
45+
}
46+
}
47+
}
6548
}
66-
cache.put(key, total);
67-
return total;
68-
}
69-
70-
private static final List<long[]> LONGS = new ArrayList<>();
71-
72-
static {
73-
LONGS.add(new long[] {1});
49+
long w = dp[m][hs];
50+
long r = f[m] * f[l - m] % M;
51+
for (int d = 0; d <= 9; d++) {
52+
r = r * invF[c[d]] % M;
53+
}
54+
r = r * w % M;
55+
return (int) r;
7456
}
7557

76-
private static long choose(int a, int b) {
77-
while (a >= LONGS.size()) {
78-
long[] prev = LONGS.get(LONGS.size() - 1);
79-
long[] next = new long[prev.length + 1];
80-
for (int i = 0; i < prev.length; i++) {
81-
next[i] = (next[i] + prev[i]) % M;
82-
next[i + 1] = prev[i];
58+
private long modInverse(long a, int m) {
59+
long r = 1;
60+
long p = m - 2;
61+
long b = a;
62+
while (p > 0) {
63+
if ((p & 1) == 1) {
64+
r = r * b % m;
8365
}
84-
LONGS.add(next);
85-
}
86-
if (a - b < b) {
87-
b = a - b;
66+
b = b * b % m;
67+
p >>= 1;
8868
}
89-
if (b < 0) {
69+
return r;
70+
}
71+
72+
private long comb(int n, int k, long[] f, long[] invF, int m) {
73+
if (k > n) {
9074
return 0;
9175
}
92-
return LONGS.get(a)[b];
76+
return f[n] * invF[k] % m * invF[n - k] % m;
9377
}
9478
}

0 commit comments

Comments
 (0)