You are given a 0-indexed integer array nums
of length n
.
nums
contains a valid split at index i
if the following are true:
i + 1
elements is greater than or equal to the sum of the last n - i - 1
elements.i
. That is, 0 <= i < n - 1
.Return the number of valid splits in nums
.
Example 1:
Input: nums = [10,4,-8,7] Output: 2 Explanation: There are three ways of splitting nums into two non-empty parts: - Split nums at index 0. Then, the first part is [10], and its sum is 10. The second part is [4,-8,7], and its sum is 3. Since 10 >= 3, i = 0 is a valid split. - Split nums at index 1. Then, the first part is [10,4], and its sum is 14. The second part is [-8,7], and its sum is -1. Since 14 >= -1, i = 1 is a valid split. - Split nums at index 2. Then, the first part is [10,4,-8], and its sum is 6. The second part is [7], and its sum is 7. Since 6 < 7, i = 2 is not a valid split. Thus, the number of valid splits in nums is 2.
Example 2:
Input: nums = [2,3,1,0] Output: 2 Explanation: There are two valid splits in nums: - Split nums at index 1. Then, the first part is [2,3], and its sum is 5. The second part is [1,0], and its sum is 1. Since 5 >= 1, i = 1 is a valid split. - Split nums at index 2. Then, the first part is [2,3,1], and its sum is 6. The second part is [0], and its sum is 0. Since 6 >= 0, i = 2 is a valid split.
Constraints:
2 <= nums.length <= 105
-105 <= nums[i] <= 105
This problem asks us to find the number of ways to split an array nums
into two non-empty subarrays such that the sum of the first subarray is greater than or equal to the sum of the second subarray.
The most efficient approach utilizes the concept of prefix sums. Instead of repeatedly calculating sums of subarrays, we pre-compute the prefix sum array. This significantly reduces the time complexity.
Calculate Total Sum: First, we calculate the total sum (s
) of all elements in nums
.
Iterate and Compare: We iterate through the array nums
up to the second to last element (because we need at least one element in the second subarray). For each index i
:
prefix sum
(t
) representing the sum of elements from index 0 to i
.prefix sum
(t
) is greater than or equal to the remaining sum (s - t
). If it is, we increment the count of valid splits (ans
).Return Count: After iterating through all possible split points, we return the final count of valid splits (ans
).
Time Complexity: O(n), where n is the length of the input array nums
. We iterate through the array once to calculate the total sum and then iterate again (up to n-1 times) to check the split conditions. The prefix sum calculation is linear.
Space Complexity: O(1). We use only a few constant extra variables to store the total sum, prefix sum, and the count of valid splits. We don't use any extra space proportional to the input size.
class Solution:
def waysToSplitArray(self, nums: List[int]) -> int:
s = sum(nums) # Calculate total sum
ans = t = 0 # Initialize count and prefix sum
for x in nums[:-1]: # Iterate up to second to last element
t += x # Update prefix sum
if t >= s - t: # Check split condition
ans += 1 # Increment count if valid
return ans
class Solution {
public int waysToSplitArray(int[] nums) {
long s = 0; // use long to avoid potential integer overflow
for (int x : nums) {
s += x;
}
long t = 0;
int ans = 0;
for (int i = 0; i < nums.length - 1; ++i) {
t += nums[i];
if (t >= s - t) {
ans++;
}
}
return ans;
}
}
The Java and other language implementations follow the same logic, adapting the syntax to the specific language. The key is the efficient use of prefix sums to avoid redundant calculations.