File tree

1 file changed

+65
-0
lines changed

1 file changed

+65
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
const MOD = BigInt(1e9 + 7);
2+
3+
var countBalancedPermutations = function (num) {
4+
let tot = 0;
5+
const n = num.length;
6+
const cnt = new Array(10).fill(0);
7+
8+
// Count the frequency of each digit in num
9+
for (const ch of num) {
10+
const d = parseInt(ch);
11+
cnt[d]++;
12+
tot += d; // Total sum of digits
13+
}
14+
15+
// If the total sum is odd, we cannot divide it into two equal parts
16+
if (tot % 2 !== 0) {
17+
return 0;
18+
}
19+
20+
const target = tot / 2; // Half of the total sum
21+
const maxOdd = Math.floor((n + 1) / 2); // Maximum possible odd positions
22+
23+
// Precompute binomial coefficients using Pascal's triangle
24+
const comb = new Array(maxOdd + 1);
25+
for (let i = 0; i <= maxOdd; i++) {
26+
comb[i] = new Array(maxOdd + 1).fill(0n);
27+
comb[i][i] = comb[i][0] = 1n;
28+
for (let j = 1; j < i; j++) {
29+
comb[i][j] = (comb[i - 1][j] + comb[i - 1][j - 1]) % MOD;
30+
}
31+
}
32+
33+
// DP table to store results: f[curr][oddCnt] is the number of ways to get sum 'curr' with 'oddCnt' odd digits
34+
const f = new Array(Number(target) + 1);
35+
for (let i = 0; i <= Number(target); i++) {
36+
f[i] = new Array(maxOdd + 1).fill(0n);
37+
}
38+
f[0][0] = 1n;
39+
40+
let psum = 0, totSum = 0;
41+
42+
// Loop through each digit from 0 to 9
43+
for (let i = 0; i <= 9; i++) {
44+
psum += cnt[i]; // Sum of the number of digits <= i
45+
totSum += i * cnt[i]; // Total sum of digits <= i
46+
47+
// Try all combinations of odd and even positioned digits
48+
for (let oddCnt = Math.min(psum, maxOdd); oddCnt >= Math.max(0, psum - (n - maxOdd)); oddCnt--) {
49+
const evenCnt = psum - oddCnt;
50+
51+
for (let curr = Math.min(totSum, target); curr >= Math.max(0, totSum - target); curr--) {
52+
let res = 0n;
53+
// Try all valid splits of the current digit into odd and even positions
54+
for (let j = Math.max(0, cnt[i] - evenCnt); j <= Math.min(cnt[i], oddCnt) && i * j <= curr; j++) {
55+
const ways = (comb[oddCnt][j] * comb[evenCnt][cnt[i] - j]) % MOD;
56+
res = (res + ((ways * f[curr - i * j][oddCnt - j]) % MOD)) % MOD;
57+
}
58+
f[curr][oddCnt] = res % MOD;
59+
}
60+
}
61+
}
62+
63+
// Return the result for the target sum with the maximum number of odd digits
64+
return Number(f[target][maxOdd]);
65+
};

0 commit comments

Comments
 (0)