548. Split Array with Equal Sum
阿新 • • 發佈:2018-11-08
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]; } }