548. Split Array with Equal Sum

Given an array with n integers, you need to find if there are triplets (i, j, k) which satisfies following conditions:
1. 0 < i, i + 1 < j, j + 1 < k < n - 1
2. Sum of subarrays (0, i - 1), (i + 1, j - 1), (j + 1, k - 1) and (k + 1, n - 1) should be equal.
where we define that subarray (L, R) represents a slice of the original array starting from the element indexed L to the element indexed R.

Example:

Input: [1,2,1,2,1,2,1]
Output: True
Explanation:
i = 1, j = 3, k = 5. 
sum(0, i - 1) = sum(0, 0) = 1
sum(i + 1, j - 1) = sum(2, 2) = 1
sum(j + 1, k - 1) = sum(4, 4) = 1
sum(k + 1, n - 1) = sum(6, 6) = 1




// 115 / 120 test cases passed
// tle when there are lots of zeros 
// how to skip zero 

class Solution {
    int[] prefix;
    public boolean splitArray(int[] nums) {
        int n = nums.length;
        prefix = new int[nums.length];
        prefix[0] = nums[0];
        for(int i = 1; i < nums.length; i++){
            prefix[i] = nums[i] + prefix[i - 1];
        }
        // can use prefix sum to preprocess the array 
        // a very brute force solution, is to pick all possible three valid points and check if the four subarray sum is the same         // time compleixty is n ^ 3 
        // dfs 
        for(int i = 1; i < nums.length - 5; i++){
            for(int j = i + 2; j < nums.length - 2; j++){
                for(int k = j + 2; k < nums.length - 1; k++){
                    int one = subsum(0, i - 1, nums);
                    int two = subsum(i + 1, j - 1, nums);
                    int three = subsum(j + 1, k - 1, nums);
                    int four = subsum(k + 1, n - 1, nums);
                    if(one == two && two == three && three == four) return true;
                }
            }
        }
        return false;  
    }
    private int subsum(int start, int end, int[] nums){
        return prefix[end] - prefix[start] + nums[start];
        
    }
}




// use space to optimize time complexity 
 

class Solution {
    int[] prefix;
    public boolean splitArray(int[] nums) {
        int n = nums.length;
        // still use prefix sum to get subarray sum in o(1) time 
        // cut the middle first (iterate j )
        // and then cut the left part (iterate i)
        // use a hashset to store the sum if the first two parts have equal sum, and then cut the right part (iterate k )
        // if the right part have equal sum and their sum exists in the hashset, return true 
        // time : n * ( 1/2 n + 1/ 2 n ) = n * n 
        prefix = new int[nums.length];
        prefix[0] = nums[0];
        for(int i = 1; i < nums.length; i++){
            prefix[i] = prefix[i - 1] + nums[i];
        }
        
        for(int j = 3; j < nums.length - 3; j++){
            HashSet<Integer> set = new HashSet<>();
            // cut left , i 
            for(int i = 1; i + 1 < j; i++){
                int one = subsum(0, i - 1, nums);
                int two = subsum(i + 1, j - 1, nums);
                if(one == two) set.add(one);
            }
            
            // cut right, j 
            for(int k = j + 2; k < n - 1; k++){
                int three = subsum(j + 1, k - 1, nums);
                int four = subsum(k + 1, n - 1, nums);
                if(three == four && set.contains(three)) return true;
            }
            
        }
        return false;
        
    }
    private int subsum(int start, int end, int[] nums){
        return prefix[end] - prefix[start] + nums[start];  
    }
}

猜你喜欢

转载自www.cnblogs.com/tobeabetterpig/p/9927010.html
今日推荐