Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Drop two elements to split the array to three part evenly in O(n)

Tags:

java

algorithm

I encounter a problem to let you drop two elements in an array to make the three part's sum equal.

  Ex:
  1 2 4 3 5 2 1
  After I drop the 4 and 5, it becomes 1, 2 | 3 | 2, 1

Constraints:

  1.Numbers are all integer > 0

  2.Drop two elements in the array, so the three splitted subarrays will have same subarray sum.

I have tried it by using two pass algorithm as the following

First pass:O(n) Count the accumulated sum from the left so I can get the range sum easily.

Second pass:O(n^2) Use nested loop to get the subarray's start and end index. Then, calculate the left, mid, right sum.

// 1.get accumulated sum map
int[] sumMap = new int[A.length];
int sum = 0;
for(int i = 0; i < A.length; i ++) {
    sum += A[i];
    sumMap[i] = sum;
}

// 2.try each combination
for(int i = 1; i < A.length - 1; i ++) {
    for(int j = i + 1; j < A.length - 1; j ++) {
        int left = sumMap[i] - A[i];
        int mid = sumMap[j] - sumMap[i] - A[j];
        int right = sumMap[A.length - 1] - sumMap[j];

        if(left == mid && mid == right)return true;
    }
}

Are there any better algorithm that can achieve O(n)?

Thanks

like image 635
Jason Avatar asked Oct 02 '18 01:10

Jason


People also ask

How do you split an array into 3 parts?

An efficient solution is to first find the sum S of all array elements. Check if this sum is divisible by 3 or not. This is because if sum is not divisible then the sum cannot be split in three equal sum sets. If there are three contiguous subarrays with equal sum, then sum of each subarray is S/3.

How do you split an array evenly?

Splitting the Array Into Even Chunks Using slice() Method The easiest way to extract a chunk of an array, or rather, to slice it up, is the slice() method: slice(start, end) - Returns a part of the invoked array, between the start and end indices.


1 Answers

Assuming that first and last element can't be dropped and all elements are >0:

Set a variable sumleft to value of first element, sumright to value of last element. You also need index variables to remember which elements from left and right were already added to the sums.

  1. If sumleft == sumright, test if next elements from left and right can be dropped to fulfill requirement. If so -> done. If not take next elements from left and right and add it to the respective sum variable. Back to 1.

  2. If sumleft < sumright, add next value from the left to sumleft. Back to 1.

  3. If sumleft > sumright, add next value from the right to sumright. Back to 1.

If all elements were consumed, there is no solution.

Edit: Testing if requirement is fulfilled when sumleft == sumright can be done by initially summing up all elements (also needs only O(n)) and checking if this sum minus the elements to drop is equal sumleft * 3.

like image 93
Michael Butscher Avatar answered Sep 22 '22 07:09

Michael Butscher