Welcome to Subscribe On Youtube
Formatted question description: https://leetcode.ca/all/548.html
548. Split Array with Equal Sum
Level
Medium
Description
Given an array with n integers, you need to find if there are triplets (i, j, k) which satisfies following conditions:
- 0 < i, i + 1 < j, j + 1 < k < n - 1
- 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
Note:
- 1 <= n <= 2000.
- Elements in the given array will be in range [-1,000,000, 1,000,000].
Solution
Several solutions exist for this problem. One solution is to use dynamic programming.
Create a 2D array dp
of type Set<Integer>
with nums.length
rows and 5 columns, where dp[i][j]
represents the possible sums when the subarray nums[0..i]
is split into j
parts. For 0 <= i < nums.length
, dp[i][1]
contains the value that equals the sum of all the elements in nums[0..i]
.
Then for 2 <= i < nums.length
and for 2 <= j <= 4
, loop over k
from i
to 2
, and let sum
be the sum of all the elements in nums[k..i]
. If dp[k - 2][j - 1]
contains sum
, then add sum
to dp[i][j]
.
Finally, return true
if and only if dp[nums.length - 1][4]
is not empty.
-
class Solution { public boolean splitArray(int[] nums) { if (nums == null || nums.length < 7) return false; int length = nums.length; Set<Integer>[][] dp = new Set[length][5]; for (int i = 0; i < length; i++) { for (int j = 1; j <= 4; j++) dp[i][j] = new HashSet<Integer>(); } int sum = 0; for (int i = 0; i < length; i++) { sum += nums[i]; dp[i][1].add(sum); } for (int i = 2; i < length; i++) { for (int j = 2; j <= 4; j++) { sum = 0; for (int k = i; k >= 2; k--) { sum += nums[k]; if (dp[k - 2][j - 1].contains(sum)) dp[i][j].add(sum); } } } return dp[length - 1][4].size() > 0; } }
-
Todo
-
class Solution: def splitArray(self, nums: List[int]) -> bool: n = len(nums) s = [0] * (n + 1) for i, v in enumerate(nums): s[i + 1] = s[i] + v for j in range(3, n - 3): seen = set() for i in range(1, j - 1): if s[i] == s[j] - s[i + 1]: seen.add(s[i]) for k in range(j + 2, n - 1): if s[n] - s[k + 1] == s[k] - s[j + 1] and s[n] - s[k + 1] in seen: return True return False ############ class Solution(object): def splitArray(self, nums): """ :type nums: List[int] :rtype: bool """ dp = [0] * (len(nums) + 1) for i in range(len(nums)): dp[i + 1] = dp[i] + nums[i] def split(start, end): return set( [dp[mid] - dp[start] for mid in range(start + 1, end) if dp[mid] - dp[start] == dp[end + 1] - dp[mid + 1]]) return any(split(0, i - 1) & split(i + 1, len(nums) - 1) for i in range(3, len(nums) - 3))