In LeetCode 2270: Number of Ways to Split Array, we must count how many partition indices i divide a 0-indexed integer array nums of length n into two non-empty subarrays such that the sum of the left prefix is greater than or equal to the sum of the right suffix. By replacing an auxiliary O(N) prefix-sum array with two 64-bit running accumulators, we achieve optimal O(N) linear time and O(1) auxiliary space.
Problem Statement & Formal Constraints
You are given a 0-indexed integer array nums of length n. The array nums contains a valid split at index i if both conditions hold:
- The sum of the first
i + 1elements (indices0throughi) is greater than or equal to the sum of the remainingn - i - 1elements (indicesi + 1throughn - 1). - There is at least one element to the right of
i, meaning0 ≤ i < n - 1.
Return the total number of valid splits in nums.
Example Walkthroughs
Example 1:
Input: nums = [10, 4, -8, 7]
Output: 2
Explanation:
- Split at i = 0: left = [10] (sum = 10), right = [4, -8, 7] (sum = 3). Since 10 >= 3, valid.
- Split at i = 1: left = [10, 4] (sum = 14), right = [-8, 7] (sum = -1). Since 14 >= -1, valid.
- Split at i = 2: left = [10, 4, -8] (sum = 6), right = [7] (sum = 7). Since 6 < 7, invalid.
Total valid splits = 2.
Example 2:
Input: nums = [2, 3, 1, 0]
Output: 2
Explanation:
- Split at i = 0: left = [2] (sum = 2), right = [3, 1, 0] (sum = 4). Invalid.
- Split at i = 1: left = [2, 3] (sum = 5), right = [1, 0] (sum = 1). Valid.
- Split at i = 2: left = [2, 3, 1] (sum = 6), right = [0] (sum = 0). Valid.
Constraints & 64-Bit Overflow Analysis
2 ≤ nums.length ≤ 105-105 ≤ nums[i] ≤ 105
Critical Systems Note: If all 105 elements equal 105, the total sum reaches 1010, which overflows a 32-bit signed integer (INT_MAX = 2,147,483,647). You must use 64-bit integers (long long / int64_t in C++) or IEEE-754 double-precision safe integers (up to 253 - 1 in TypeScript/JavaScript) to prevent signed integer overflow undefined behavior.
Optimal Algorithm: O(1) Space Prefix & Suffix Accumulators
Mathematical Formulation
Instead of allocating an O(N) prefix sum vector, we first compute the total sum of the array into rightSum. Then, as index i advances from 0 to n - 2, we transfer nums[i] from the right partition to the left partition in O(1) time:
leftSum += nums[i]rightSum -= nums[i]- Increment
countwheneverleftSum >= rightSum.
C++20 Implementation
#include <vector>
#include <cstdint>
class Solution {
public:
int waysToSplitArray(const std::vector<int>& nums) {
int64_t leftSum = 0;
int64_t rightSum = 0;
for (int num : nums) {
rightSum += num;
}
int validSplits = 0;
const std::size_t limit = nums.size() - 1;
for (std::size_t i = 0; i < limit; ++i) {
leftSum += nums[i];
rightSum -= nums[i];
if (leftSum >= rightSum) {
++validSplits;
}
}
return validSplits;
}
};
TypeScript Implementation
export function waysToSplitArray(nums: number[]): number {
let rightSum = 0;
for (let i = 0; i < nums.length; i++) {
rightSum += nums[i];
}
let leftSum = 0;
let validSplits = 0;
const lastSplitIndex = nums.length - 1;
for (let i = 0; i < lastSplitIndex; i++) {
leftSum += nums[i];
rightSum -= nums[i];
if (leftSum >= rightSum) {
validSplits++;
}
}
return validSplits;
}
Complexity Comparison
| Approach | Time Complexity | Auxiliary Space | Notes |
|---|---|---|---|
| Brute-Force Nested Loops | O(N2) |
O(1) |
Recomputes left/right subarray sums for each split index; TLE at N = 105. |
| Prefix Sum Array | O(N) |
O(N) |
Allocates 800 KB heap vector for 105 64-bit prefix sums. |
| Running Prefix/Suffix Accumulators | O(N) |
O(1) |
Two sequential scalar scans in CPU registers; zero heap allocations. |
