2270. Number of Ways to Split Array - Explanation
Prerequisites
Before attempting this problem, you should be comfortable with:
- Prefix Sum - Computing cumulative sums to efficiently calculate subarray sums in O(1) time
- Array Traversal - Iterating through arrays and maintaining running totals
- Integer Overflow - Understanding when to use long/long long for large sums
1. Brute Force
Intuition
A valid split at index i means the sum of elements from 0 to i is at least as large as the sum from i+1 to the end. The straightforward approach is to compute both sums for every possible split point by iterating through the relevant portions of the array each time.
Algorithm
- For each possible split index
ifrom0ton - 2:- Compute
leftSumby iterating from0toi. - Compute
rightSumby iterating fromi + 1ton - 1. - If
leftSum >= rightSum, incrementres.
- Compute
- Return the count of valid splits.
class Solution:
def waysToSplitArray(self, nums: List[int]) -> int:
n = len(nums)
res = 0
for i in range(n - 1):
leftSum = 0
for j in range(i + 1):
leftSum += nums[j]
rightSum = 0
for j in range(i + 1, n):
rightSum += nums[j]
res += (1 if leftSum >= rightSum else 0)
return resTime & Space Complexity
- Time complexity:
- Space complexity:
2. Prefix Sum
Intuition
Recomputing sums from scratch for each split is wasteful. By precomputing a prefix sum array, we can find the sum of any subarray in constant time. The left sum up to index i is prefix[i], and the right sum is prefix[n] - prefix[i].
Algorithm
- Build a prefix sum array where
prefix[i]is the sum of the firstielements. - For each split index
ifrom1ton - 1:left = prefix[i].right = prefix[n] - prefix[i].- If
left >= right, incrementres.
- Return the count.
class Solution:
def waysToSplitArray(self, nums: List[int]) -> int:
n = len(nums)
prefix = [0] * (n + 1)
for i in range(n):
prefix[i + 1] = prefix[i] + nums[i]
res = 0
for i in range(1, n):
left = prefix[i]
right = prefix[n] - prefix[i]
if left >= right:
res += 1
return resTime & Space Complexity
- Time complexity:
- Space complexity:
3. Prefix Sum (Optimal)
Intuition
We don't need to store the entire prefix sum array. Instead, we can maintain a running left sum and right sum. Start with right as the total, then shift elements from right to left as we iterate through possible split points.
Algorithm
- Compute the total sum and assign it to
right. - Initialize
left = 0andres = 0. - For each index
ifrom0ton - 2:- Add
nums[i]toleftand subtract it fromright. - If
left >= right, incrementres.
- Add
- Return
res.
Time & Space Complexity
- Time complexity:
- Space complexity:
Common Pitfalls
Off-by-One Error in Loop Bounds
The split must have at least one element on each side, so valid split indices are from 0 to n-2 (inclusive). A common mistake is iterating up to n-1, which would leave the right side empty. Always ensure the loop condition is i < n - 1 or equivalent.
Integer Overflow with Large Sums
The array can contain values up to 10^9 and have up to 10^5 elements, so the total sum can exceed the 32-bit integer range. Using int for sums in Java, C++, or similar languages causes overflow and incorrect comparisons. Always use long or long long for the sum variables.
Comparing Sums Before Updating Them
In the optimal one-pass approach, the order of operations matters. You must first add nums[i] to left and subtract from right, then compare. A common bug is comparing before updating, which checks the wrong split point. The correct sequence is: update sums, then check if left >= right.