Balanced Mod Subarrays
Each number belongs to one of three remainder groups based on num % 3. This problem asks you to return every maximal balanced subarray, where a balanced subarray has the same count of remainder 0, remainder 1, and remainder 2 values.
The word maximal matters here. You are not returning every balanced piece. You only return the longest ones that cannot be extended left or right without breaking the balance.
For example, [0,1,2,3,4,5] is itself balanced because it contains two values from each remainder group, so the whole array is returned. In [1,4,7,10], every value has remainder 1, so there is no balanced subarray at all and the answer is [].
So the task is to find all continuous ranges where the three remainder groups are equally represented, then keep only the ranges that are maximal.
Example Input & Output
The entire array has two values from each remainder class and is maximal.
Two maximal balanced subarrays cover the timeline; neither can be extended without breaking the balance.
All values share the same remainder, so no balanced subarray exists.
Algorithm Flow

Solution Approach
A useful trick here is to track how the remainder counts differ from each other as you move through the array. Let the running counts be c0, c1, and c2. A subarray is balanced when those counts increase by the same amount, which means the pair of differences stays the same at both ends.
One compact state is:
If the same state appears at two prefix positions, then the subarray between them is balanced.
So we scan the array, store the earliest and latest places where each state appears, and use those matches to recover balanced ranges. After that, we keep only the ones that are maximal instead of returning smaller balanced ranges sitting inside a larger one.
This approach avoids checking every possible subarray directly. With hashing on the prefix states, it runs in linear time relative to the array size, plus the work needed to build the final list of maximal ranges.
Best Answers
import java.util.*;
class Solution {
public int[][] find_maximal_balanced_subarrays(int[] nums) {
int p0 = 0, p1 = 0, p2 = 0;
Map<String, List<Integer>> diffs = new HashMap<>();
diffs.computeIfAbsent("0,0", k -> new ArrayList<>()).add(-1);
for (int i = 0; i < nums.length; i++) {
int r = (nums[i] % 3 + 3) % 3;
if (r == 0) p0++;
else if (r == 1) p1++;
else p2++;
String key = (p0 - p1) + "," + (p1 - p2);
diffs.computeIfAbsent(key, k -> new ArrayList<>()).add(i);
}
List<int[]> balanced = new ArrayList<>();
for (List<Integer> indices : diffs.values()) {
for (int a = 0; a < indices.size(); a++) {
for (int b = a + 1; b < indices.size(); b++) {
balanced.add(new int[]{indices.get(a) + 1, indices.get(b)});
}
}
}
List<int[]> maximal = new ArrayList<>();
for (int[] b1 : balanced) {
boolean isSub = false;
for (int[] b2 : balanced) {
if (b2[0] <= b1[0] && b2[1] >= b1[1] && (b2[0] != b1[0] || b2[1] != b1[1])) {
isSub = true;
break;
}
}
if (!isSub) maximal.add(b1);
}
maximal.sort(Comparator.comparingInt(a -> a[0]));
int[][] result = new int[maximal.size()][];
for (int i = 0; i < maximal.size(); i++) {
int start = maximal.get(i)[0];
int end = maximal.get(i)[1];
result[i] = Arrays.copyOfRange(nums, start, end + 1);
}
return result;
}
}Comments (0)
Join the Discussion
Share your thoughts, ask questions, or help others with this Challenge.
