Problem Description
Given an array arr consisting of only zeros and ones, divide the array into three non-empty parts such that each part represents the same binary value. Here, the entire part (including any leading zeros) is considered when determining the binary value. If such a division is possible, return any [i, j] such that:
- arr[0...i] is the first part,
- arr[i+1...j-1] is the second part, and
- arr[j...end] is the third part, with i + 1 < j. If no such division exists return [-1, -1].
Key Insights
- The total number of 1's must be divisible by 3; if there are no 1's, any split works.
- Use the positions of the first 1 in each of the three parts to identify a candidate pattern.
- The pattern (subarray starting at these indices) must be the same for each part. Additionally, there must be enough zeros at the end of the array to cover any trailing zeros.
- Walking through the array in a single pass helps track where parts should begin.
Space and Time Complexity
Time Complexity: O(n) where n is the length of the array. Space Complexity: O(1)
Solution
The solution first counts the total ones. If the count is 0, then the array has only zeros and any valid partition works (e.g., [0, length - 1]). If the total number of 1's is not divisible by 3, the answer is [-1, -1]. Otherwise, we determine the starting indices for the first 1 in each of the three parts. The idea is to use the third part as the "pattern" reference, and then match the corresponding portions in the first and second parts against it. Finally, we check that there are enough trailing zeros after the identified pattern to make the three parts valid. This approach relies only on pointer manipulations and simple comparisons, giving an efficient linear time solution with constant extra space.