Three Equal Parts

hard array binary math

Problem

You are given an array arr of 0s and 1s. Divide the array into three non-empty parts so that all of these parts represent the same binary value. Return any [i, j] with i + 1 < j such that arr[0..i] is the first part, arr[i+1..j-1] is the second part, and arr[j..n-1] is the third part, and all three parts represent the same binary value. If it is not possible, return [-1, -1].

Inputarr = [1, 0, 1, 0, 1]
Output[0, 3]
Parts are [1], [0,1], [0,1] — each represents the binary value 1.

def three_equal_parts(arr):
    total = sum(arr)
    if total % 3 != 0:
        return [-1, -1]
    if total == 0:
        return [0, len(arr) - 1]
    k = total // 3
    n = len(arr)
    ones = [i for i, v in enumerate(arr) if v == 1]
    s1, s2, s3 = ones[0], ones[k], ones[2 * k]
    length = n - s3
    if s1 + length > s2 or s2 + length > s3:
        return [-1, -1]
    for d in range(length):
        if arr[s1 + d] != arr[s2 + d] or arr[s2 + d] != arr[s3 + d]:
            return [-1, -1]
    return [s1 + length - 1, s2 + length]
function threeEqualParts(arr) {
  const total = arr.reduce((a, b) => a + b, 0);
  if (total % 3 !== 0) return [-1, -1];
  if (total === 0) return [0, arr.length - 1];
  const k = total / 3, n = arr.length;
  const ones = [];
  for (let i = 0; i < n; i++) if (arr[i] === 1) ones.push(i);
  const s1 = ones[0], s2 = ones[k], s3 = ones[2 * k];
  const length = n - s3;
  if (s1 + length > s2 || s2 + length > s3) return [-1, -1];
  for (let d = 0; d < length; d++) {
    if (arr[s1 + d] !== arr[s2 + d] || arr[s2 + d] !== arr[s3 + d]) return [-1, -1];
  }
  return [s1 + length - 1, s2 + length];
}
class Solution {
    public int[] threeEqualParts(int[] arr) {
        int total = 0;
        for (int v : arr) total += v;
        if (total % 3 != 0) return new int[]{-1, -1};
        if (total == 0) return new int[]{0, arr.length - 1};
        int k = total / 3, n = arr.length;
        int s1 = -1, s2 = -1, s3 = -1, c = 0;
        for (int i = 0; i < n; i++) {
            if (arr[i] == 1) {
                if (c == 0) s1 = i;
                if (c == k) s2 = i;
                if (c == 2 * k) s3 = i;
                c++;
            }
        }
        int length = n - s3;
        if (s1 + length > s2 || s2 + length > s3) return new int[]{-1, -1};
        for (int d = 0; d < length; d++) {
            if (arr[s1 + d] != arr[s2 + d] || arr[s2 + d] != arr[s3 + d])
                return new int[]{-1, -1};
        }
        return new int[]{s1 + length - 1, s2 + length};
    }
}
vector<int> threeEqualParts(vector<int>& arr) {
    int total = 0;
    for (int v : arr) total += v;
    if (total % 3 != 0) return {-1, -1};
    if (total == 0) return {0, (int)arr.size() - 1};
    int k = total / 3, n = arr.size();
    int s1 = -1, s2 = -1, s3 = -1, c = 0;
    for (int i = 0; i < n; i++) {
        if (arr[i] == 1) {
            if (c == 0) s1 = i;
            if (c == k) s2 = i;
            if (c == 2 * k) s3 = i;
            c++;
        }
    }
    int length = n - s3;
    if (s1 + length > s2 || s2 + length > s3) return {-1, -1};
    for (int d = 0; d < length; d++) {
        if (arr[s1 + d] != arr[s2 + d] || arr[s2 + d] != arr[s3 + d])
            return {-1, -1};
    }
    return {s1 + length - 1, s2 + length};
}
Time: O(n) Space: O(n)