Approach
Sorting and greedy selection
For Count Number of Balanced Permutations, the implementation first exposes a useful order, then scans that order while making locally justified choices.
- Choose the key that reveals the greedy or grouping structure.
- Sort the relevant records by that key.
- Scan in order, maintaining the invariant that makes each local choice safe.
Code notes
- 100 lines of Java from the credited upstream file 3343.java.
- The implementation visibly relies on sequence storage.
- 7 loop blocks detected.
Complexity
Sorting is typically the dominant term unless the subsequent scan uses a more expensive nested operation.
Check the problem constraints before deciding whether this complexity will pass.
Use this to learn the idea, then write your own version.
1class Solution {2 public int countBalancedPermutations(String num) {3 int[] nums = getNums(num);4 final int sum = Arrays.stream(nums).sum();5 if (sum % 2 == 1)6 return 0;7 8 Arrays.sort(nums);9 reverse(nums, 0, nums.length - 1);10 11 final int even = (nums.length + 1) / 2;12 final int odd = nums.length / 2;13 final int evenBalance = sum / 2;14 Long[][][] mem = new Long[even + 1][odd + 1][evenBalance + 1];15 final long perm = getPerm(nums);16 return (17 int) ((countBalancedPermutations(nums, even, odd, evenBalance, mem) * modInverse(perm)) %18 MOD);19 }20 21 private static final int MOD = 1_000_000_007;22 23 24 25 26 private long countBalancedPermutations(int[] nums, int even, int odd, int evenBalance,27 Long[][][] mem) {28 if (evenBalance < 0)29 return 0;30 if (even == 0)31 return evenBalance == 0 ? factorial(odd) : 0;32 final int index = nums.length - (even + odd);33 if (odd == 0) {34 long remainingSum = 0;35 for (int i = index; i < nums.length; ++i)36 remainingSum += nums[i];37 return remainingSum == evenBalance ? factorial(even) : 0;38 }39 if (mem[even][odd][evenBalance] != null)40 return mem[even][odd][evenBalance];41 final long placeEven =42 countBalancedPermutations(nums, even - 1, odd, evenBalance - nums[index], mem) * even % MOD;43 final long placeOdd =44 countBalancedPermutations(nums, even, odd - 1, evenBalance, mem) * odd % MOD;45 return mem[even][odd][evenBalance] = (placeEven + placeOdd) % MOD;46 }47 48 private int[] getNums(String num) {49 int[] nums = new int[num.length()];50 for (int i = 0; i < num.length(); ++i)51 nums[i] = num.charAt(i) - '0';52 return nums;53 }54 55 private long getPerm(int[] nums) {56 long res = 1;57 int[] count = new int[10];58 for (final int num : nums)59 ++count[num];60 for (final int freq : count)61 res = res * factorial(freq) % MOD;62 return res;63 }64 65 private long factorial(int n) {66 long res = 1;67 for (int i = 2; i <= n; ++i)68 res = res * i % MOD;69 return res;70 }71 72 private long modInverse(long a) {73 long m = MOD;74 long y = 0;75 long x = 1;76 while (a > 1) {77 final long q = a / m;78 long t = m;79 m = a % m;80 a = t;81 t = y;82 y = x - q * y;83 x = t;84 }85 86 return x < 0 ? x + MOD : x;87 }88 89 private void reverse(int[] nums, int l, int r) {90 while (l < r)91 swap(nums, l++, r--);92 }93 94 private void swap(int[] nums, int i, int j) {95 final int temp = nums[i];96 nums[i] = nums[j];97 nums[j] = temp;98 }99}100