Number of Ways to Split Array
Problem Statement​
In this tutorial, we will solve the Number of Ways to Split Array problem . We will provide the implementation of the solution in Python, Java, and C++.
Problem Description​
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:
The sum of the first i + 1 elements is greater than or equal to the sum of the last n - i - 1 elements. There is at least one element to the right of i. That is, 0 <= i < n - 1. Return the number of valid splits in nums.
Examples​
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
Solution of Given Problem​
Intuition and Approach​
The problem can be solved using a brute force approach or an optimized Technique.
- Brute Force
 - Optimized approach
 
Approach 1:Brute Force (Naive)​
Brute Force Approach: In the brute force approach, we will iterate through all possible split points and check if the condition of a valid split is satisfied.
Codes in Different Languages​
- C++
 - Java
 - Python
 
#include <vector>
#include <numeric>
#include <iostream>
int validSplitsBruteForce(const std::vector<int>& nums) {
    int n = nums.size();
    int count = 0;
    for (int i = 0; i < n - 1; ++i) {
        int leftSum = std::accumulate(nums.begin(), nums.begin() + i + 1, 0);
        int rightSum = std::accumulate(nums.begin() + i + 1, nums.end(), 0);
        if (leftSum >= rightSum) {
            count++;
        }
    }
    return count;
}
int main() {
    std::vector<int> nums = {10, 4, -8, 7};
    std::cout << "Number of valid splits: " << validSplitsBruteForce(nums) << std::endl;
    return 0;
}
import java.util.*;
public class Main {
    public static int validSplitsBruteForce(int[] nums) {
        int n = nums.length;
        int count = 0;
        for (int i = 0; i < n - 1; ++i) {
            int leftSum = 0, rightSum = 0;
            for (int j = 0; j <= i; ++j) {
                leftSum += nums[j];
            }
            for (int j = i + 1; j < n; ++j) {
                rightSum += nums[j];
            }
            if (leftSum >= rightSum) {
                count++;
            }
        }
        return count;
    }
    public static void main(String[] args) {
        int[] nums = {10, 4, -8, 7};
        System.out.println("Number of valid splits: " + validSplitsBruteForce(nums));
    }
}
def valid_splits_brute_force(nums):
    n = len(nums)
    count = 0
    for i in range(n - 1):
        left_sum = sum(nums[:i + 1])
        right_sum = sum(nums[i + 1:])
        if left_sum >= right_sum:
            count += 1
    return count
nums = [10, 4, -8, 7]
print("Number of valid splits:", valid_splits_brute_force(nums))
Complexity Analysis​
- Time Complexity:
 - because for each split point, we calculate the sum of the left and right parts independently, leading to nested iterations.
 - Space Complexity:
 - as no extra space is used other than a few variables for counting and summing.
 
Approach 2: Optimized approach​
Optimized Approach: In the optimized approach, we will use prefix sums to avoid recalculating the sum of elements multiple times.
Code in Different Languages​
- C++
 - Java
 - Python
 
#include <vector>
#include <iostream>
int validSplitsOptimized(const std::vector<int>& nums) {
    int n = nums.size();
    int totalSum = 0;
    for (int num : nums) {
        totalSum += num;
    }
    int leftSum = 0, count = 0;
    for (int i = 0; i < n - 1; ++i) {
        leftSum += nums[i];
        if (leftSum >= totalSum - leftSum) {
            count++;
        }
    }
    return count;
}
int main() {
    std::vector<int> nums = {10, 4, -8, 7};
    std::cout << "Number of valid splits: " << validSplitsOptimized(nums) << std::endl;
    return 0;
}
public class Main {
    public static int validSplitsOptimized(int[] nums) {
        int n = nums.length;
        int totalSum = 0;
        for (int num : nums) {
            totalSum += num;
        }
        int leftSum = 0, count = 0;
        for (int i = 0; i < n - 1; ++i) {
            leftSum += nums[i];
            if (leftSum >= totalSum - leftSum) {
                count++;
            }
        }
        return count;
    }
    public static void main(String[] args) {
        int[] nums = {10, 4, -8, 7};
        System.out.println("Number of valid splits: " + validSplitsOptimized(nums));
    }
}
def valid_splits_optimized(nums):
    n = len(nums)
    total_sum = sum(nums)
    left_sum = 0
    count = 0
    for i in range(n - 1):
        left_sum += nums[i]
        if left_sum >= total_sum - left_sum:
            count += 1
    return count
nums = [10, 4, -8, 7]
print("Number of valid splits:", valid_splits_optimized(nums))
Complexity Analysis​
- Time Complexity:
 - because we compute the total sum once and then iterate through the array once to update the left sum and check the condition.
 - Space Complexity:
 - as only a few variables are used for summing and counting.
 - This approach is efficient and straightforward.