public class Solution {
//Here j is used for middle cut, i for left cut and k for right cut.
//Iterate middle cuts and then find left cuts which divides the first half into two equal quarters, store that quarter sums in the hashset. Then find right cuts which divides the second half into two equal quarters and check if quarter sum is present in the hashset. If yes return true.
public boolean splitArray2(int[] nums) {
if (nums.length < 7)
return false;
int[] sum = new int[nums.length];
sum[0] = nums[0];
for (int i = 1; i < nums.length; i++) {
sum[i] = sum[i - 1] + nums[i];
}
for (int j = 3; j < nums.length - 3; j++) {
HashSet < Integer > set = new HashSet < > ();
for (int i = 1; i < j - 1; i++) {
if (sum[i - 1] == sum[j - 1] - sum[i])
set.add(sum[i - 1]);
}
for (int k = j + 2; k < nums.length - 1; k++) {
if (sum[nums.length - 1] - sum[k] == sum[k - 1] - sum[j] && set.contains(sum[k - 1] - sum[j]))
return true;
}
}
return false;
}
//can give a sum boundary to accelerate the search
public boolean splitArray(int[] nums) {
int min = Integer.MAX_VALUE, max = Integer.MIN_VALUE, n = nums.length;
int[] sum = new int[n];
sum[0] = nums[0];
for(int i = 0; i < n; ++i) {
min = Math.min(min, nums[i]);
max = Math.max(max, nums[i]);
if(i > 0) sum[i] = sum[i-1] + nums[i];
}
int minSum = sum[n-1]-3*max, maxSum = sum[n-1]-3*min;
minSum = minSum < 0? minSum/4: (minSum+3)/4;
maxSum = maxSum > 0? maxSum/4: (maxSum-3)/4;
for(int i = 0; i < n - 6; ++i) {
//filter out unnecessary search by specifies the sum boundary
if(sum[i] >= minSum && sum[i] <= maxSum) {
int curr = sum[i];
for(int j = i + 2; j < n - 4; ++j) {
if(sum[j] - sum[i+1] == curr) {
for(int k = j + 2; k < n - 2; ++k) {
if(sum[k] - sum[j+1] == curr && sum[n-1] - sum[k+1] == curr) return true;
}
}
}
}
}
return false;
}
}