3343. Count Number of Balanced Permutations
Description
You are given a string num
. A string of digits is called balanced if the sum of the digits at even indices is equal to the sum of the digits at odd indices.
Return the number of distinct permutations of num
that are balanced.
Since the answer may be very large, return it modulo 109 + 7
.
A permutation is a rearrangement of all the characters of a string.
Example 1:
Input: num = "123"
Output: 2
Explanation:
- The distinct permutations of
num
are"123"
,"132"
,"213"
,"231"
,"312"
and"321"
. - Among them,
"132"
and"231"
are balanced. Thus, the answer is 2.
Example 2:
Input: num = "112"
Output: 1
Explanation:
- The distinct permutations of
num
are"112"
,"121"
, and"211"
. - Only
"121"
is balanced. Thus, the answer is 1.
Example 3:
Input: num = "12345"
Output: 0
Explanation:
- None of the permutations of
num
are balanced, so the answer is 0.
Constraints:
2 <= num.length <= 80
num
consists of digits'0'
to'9'
only.
Solutions
Solution: Dynamic Programming + Combinatorics
- Time complexity: O(n3)
- Space complexity: O(n3)
JavaScript
js
/**
* @param {string} num
* @return {number}
*/
const countBalancedPermutations = function (num) {
const MODULO = BigInt(10 ** 9 + 7);
const n = num.length;
const digits = Array.from({ length: 10 }, () => 0);
let total = 0;
for (const digit of num) {
digits[digit] += 1;
total += Number(digit);
}
if (total % 2) return 0;
const halfSize = Math.floor(n / 2);
const comb = Array.from({ length: n + 1 }, () => new Array(n + 1).fill(1n));
const memo = new Map();
for (let a = 2; a <= n; a++) {
for (let b = 1; b < a; b++) {
comb[a][b] = comb[a - 1][b - 1] + comb[a - 1][b];
}
}
const balancedPermutations = (digit, odd, even, balance) => {
if (!odd && !even && !balance) return 1n;
if (digit > 9 || odd < 0 || even < 0 || balance < 0) return 0n;
const key = `${digit},${odd},${even},${balance}`;
if (memo.has(key)) return memo.get(key);
const digitCount = digits[digit];
let result = 0n;
for (let count = 0; count <= digitCount; count++) {
const evenCount = digitCount - count;
const ways = (comb[odd][count] * comb[even][evenCount]) % MODULO;
const nextBalance = balance - digit * count;
const balanced = balancedPermutations(digit + 1, odd - count, even - evenCount, nextBalance);
result = (result + ways * balanced) % MODULO;
}
memo.set(key, result);
return result;
};
return Number(balancedPermutations(0, n - halfSize, halfSize, total / 2));
};