Talentd
FleetCode
Make and follow sheets.Sign in

Ways to Split Array Into Good Subarrays solution and explanation

MediumArrayDynamic ProgrammingMath5 min read34.9% acceptanceUpdated 9 Apr 2026
Leetcode Weekly contest 351 - Medium - Ways to Split Array Into Good SubarraysPrakhar Agrawal · 6:50 · 1K viewsWatch on YouTube
8 more videos on this problem
  1. Leetcode Weekly contest 351 - Medium - Ways to Split Array Into Good SubarraysPrakhar Agrawal · 6:50 · 1K views
  2. Leetcode 2750 Ways to Split Array Into Good SubarraysThinkCode · 6:23 · 1K views
  3. 6910. Ways to Split Array Into Good Subarrays | Leetcode | Weekly Contest 351 | Sol Code In Comment.Optimization · 0:22 · 978 views
  4. Bottom Up DP | 2750. Ways to Split Array Into Good Subarrays | Leetcode Weekly Contest 351codingMohan · 24:14 · 934 views
  5. Ways to Split Array Into Good Subarrays LeetCode Weekly Contest 351 Join Link from commentsCoding Guru · 0:39 · 428 views
  6. 2750. Ways to Split Array Into Good Subarrays (Leetcode Medium)Programming Live with Larry · 11:59 · 314 views
  7. Leetcode 2750 || Ways to Split Array Into Good Subarrays || Leetcode Weekly Medium || cppKomal Pal · 9:55 · 288 views
  8. WAYS TO SPLIT ARRAY INTO GOOD SUBARRAYS | LEETCODE WEEKLY CONTEST 351 | LEETCODE | 6910 | #leetcodeTechRats official · 7:00 · 284 views
  9. Leetcode 2750 Ways to Split Array Into Good SubarraysTech Diet · 10:39 · 125 views

The problem

You are given a binary array nums.

A subarray of an array is good if it contains exactly one element with the value 1.

Return an integer denoting the number of ways to split the array nums into good subarrays. As the number may be too large, return it modulo 109 + 7.

A subarray is a contiguous non-empty sequence of elements within an array.

Example 1:

Input: nums = [0,1,0,0,1]
Output: 3
Explanation: There are 3 ways to split nums into good subarrays:
- [0,1] [0,0,1]
- [0,1,0] [0,1]
- [0,1,0,0] [1]

Example 2:

Input: nums = [0,1,0]
Output: 1
Explanation: There is 1 way to split nums into good subarrays:
- [0,1,0]

Constraints:

  • 1 <= nums.length <= 105
  • 0 <= nums[i] <= 1

Approach overview

Problem Overview: You are given a binary array and need to count how many ways it can be split into contiguous subarrays where each subarray contains exactly one 1. Zeros can appear anywhere inside a subarray, but every segment must include one and only one 1. The task reduces to counting valid split points between consecutive ones.

Approach 1: Gap Counting Method (O(n) time, O(1) space)

The key observation: every valid subarray must contain exactly one 1. That means splits can only occur between two consecutive 1 values. Count the number of zeros between each pair of ones. If there are k zeros between them, you have k + 1 possible places to split while still keeping one 1 per segment. Multiply these choices across all adjacent pairs of ones. Implementation is straightforward: iterate through the array, record the index of the previous 1, compute the gap when the next 1 appears, and multiply the answer by that gap size. If the array contains no 1, return 0 because forming a valid subarray is impossible. This solution uses simple arithmetic and a single pass, making it the most efficient approach for array problems involving binary structure.

Approach 2: Prefix Count Method (O(n) time, O(1) space)

This version frames the problem using running counts similar to lightweight dynamic programming. Track how many zeros appear after the previous 1. When a new 1 appears, those zeros represent multiple possible boundaries for the previous segment. Maintain a running number of valid splits and update it using multiplication with zeroCount + 1. Conceptually this treats each 1 as starting a new segment while the zeros between ones determine how many prefixes can form valid partitions. The logic is almost identical to the gap method but expressed through prefix tracking instead of explicit index gaps.

Both approaches rely on a simple combinatorial insight: the total number of valid splits equals the product of choices created by zeros between ones. The computation naturally fits problems combining math reasoning with linear array traversal.

Recommended for interviews: The Gap Counting Method is what interviewers typically expect. It shows you recognized the combinatorial structure of the array instead of brute‑forcing split positions. Explaining why each zero gap contributes gap + 1 choices demonstrates strong problem decomposition and leads directly to the optimal O(n) solution.

Approach 1: Gap Counting Method

This approach involves counting the zero gaps between consecutive `1`s. Each zero gap can provide a multiplicative factor to the number of ways we can split the array around `1`s to form good subarrays. To solve this, iterate through the `nums` array, and whenever a `1` is found, calculate the number of splits using zero gaps encountered so far and multiply this with the previous result. Track the zeros between `1`s using a counter.

def countGoodSubarrays(nums):
    MOD = 10**9 + 7
    count, ways, zero_count = 0, 1, 0
    for num in nums:
        if num == 1:
            ways = (ways * (zero_count + 1)) % MOD
            zero_count = 0
            count += 1
        else:
            zero_count += 1
    return ways if count > 0 else 0
public class GoodSubarrays {
    public int countGoodSubarrays(int[] nums) {
        final int MOD = 1000000007;
        int count = 0, ways = 1, zeroCount = 0;
        for (int num : nums) {
            if (num == 1) {
                ways = (int)((long)ways * (zeroCount + 1) % MOD);
                zeroCount = 0;
                count++;
            } else {
                zeroCount++;
            }
        }
        return count > 0 ? ways : 0;
    }
}
#include <vector>
using namespace std;

class Solution {
public:
    int countGoodSubarrays(vector<int>& nums) {
        const int MOD = 1000000007;
        long long ways = 1, zeroCount = 0;
        int count = 0;
        for (int num : nums) {
            if (num == 1) {
                ways = (ways * (zeroCount + 1)) % MOD;
                zeroCount = 0;
                count++;
            } else {
                zeroCount++;
            }
        }
        return count > 0 ? ways : 0;
    }
};

We initialize our main variables: `MOD` to handle modulo operation, `ways` to calculate the number of split ways, and `zero_count` to keep track of zeros between `1`s. As we iterate, each `1` encountered helps us accumulate the result by factoring in the preceding zeros. Finally, return `ways` if there is at least one `1` in the array.

Complexity

Time Complexity: O(n) - since we only traverse the array once.
Space Complexity: O(1) - as we use a constant space to manage the counters.

Try this approach in the editor

Approach 2: Prefix Count Method

This approach leverages the counting of cumulative prefixes which might split into valid subarrays. By considering the prefix sums at each point, we deliberately choose indices to count potential good subarrays, focusing shifts for every `1` encountered.

function countGoodSubarrays(nums) {
    const MOD = 10**9 + 7;
    let ways = 1, zeroCount = 0;
    for (let num of nums) {
        if (num === 1) {
            ways = ways * (zeroCount + 1) % MOD;
            zeroCount = 0;
        } else {
            zeroCount++;
        }
    }
    return (ways === 1) ? 0 : ways;
}
public class Solution {
    public int CountGoodSubarrays(int[] nums) {
        const int MOD = 1000000007;
        int ways = 1, zeroCount = 0;
        foreach (var num in nums) {
            if (num == 1) {
                ways = (int)((long)ways * (zeroCount + 1) % MOD);
                zeroCount = 0;
            } else {
                zeroCount++;
            }
        }
        return ways == 1 ? 0 : ways;
    }
}

The JavaScript implementation aligns with the logic of leveraging prefix count and zero spans between `1`s. The calculations are wrapped efficiently within one loop using modulo to manage large results.

Complexity

Time Complexity: O(n) - directly proportional to the length of nums.
Space Complexity: O(1) - due to constant space use.

Try this approach in the editor

Approach 3: Multiplication Principle

Based on the problem description, we can draw a dividing line between two 1s. Assuming the indices of the two 1s are j and i respectively, then the number of different dividing lines that can be drawn is i - j. We find all the pairs of j and i that meet the condition, and then multiply all the i - j together. If no dividing line can be found between two 1s, it means there are no 1s in the array, and the answer is 0.

The time complexity is O(n), where n is the length of the array. The space complexity is O(1).

function numberOfGoodSubarraySplits(nums: number[]): number {
    let ans = 1;
    let j = -1;
    const mod = 10 ** 9 + 7;
    const n = nums.length;
    for (let i = 0; i < n; ++i) {
        if (nums[i] === 0) {
            continue;
        }
        if (j > -1) {
            ans = (ans * (i - j)) % mod;
        }
        j = i;
    }
    return j === -1 ? 0 : ans;
}
func numberOfGoodSubarraySplits(nums []int) int {
	const mod int = 1e9 + 7
	ans, j := 1, -1
	for i, x := range nums {
		if x == 0 {
			continue
		}
		if j > -1 {
			ans = ans * (i - j) % mod
		}
		j = i
	}
	if j == -1 {
		return 0
	}
	return ans
}
Try this approach in the editor

Complexity comparison

ApproachComplexity
Gap Counting Method

Time Complexity: O(n) - since we only traverse the array once.
Space Complexity: O(1) - as we use a constant space to manage the counters.

Prefix Count Method

Time Complexity: O(n) - directly proportional to the length of nums.
Space Complexity: O(1) - due to constant space use.

Multiplication Principle–

Complexity analysis

ApproachTimeSpaceWhen to Use
Gap Counting MethodO(n)O(1)Best general solution for binary arrays; minimal memory and clean combinatorial logic
Prefix Count MethodO(n)O(1)Useful when expressing the logic as prefix states or lightweight dynamic programming

Frequently asked questions

Is Ways to Split Array Into Good Subarrays easy or hard?

The problem is rated Medium because the implementation is simple but the key insight is not immediately obvious. Recognizing that zeros between consecutive 1s create multiple valid split points is the main step needed to derive the optimal O(n) solution.

Ways to Split Array Into Good Subarrays Python/Java solution

Most implementations follow the same pattern across languages: iterate through the array, track the previous index of 1, compute the gap when the next 1 appears, and multiply the answer by that gap size. Python, Java, and C++ implementations typically complete this in under 10 lines using simple loops.

How to solve Ways to Split Array Into Good Subarrays in O(n)?

Traverse the array and track the index of each 1. For every pair of consecutive 1s, compute the distance between them, which represents the number of valid split points. Multiply these values across all pairs. This single-pass approach yields an O(n) time solution with constant extra space.

What is the best approach for Ways to Split Array Into Good Subarrays?

The Gap Counting Method is the most efficient and commonly used solution. It counts the number of zeros between consecutive 1s and multiplies the possible split choices. If there are k zeros between two 1s, you get k+1 ways to place a boundary. This produces an O(n) time and O(1) space solution.

Is Ways to Split Array Into Good Subarrays asked at Google/Amazon/Meta?

Problems combining array traversal with combinatorial counting appear frequently in interviews at companies like Amazon, Google, and Meta. Variants often test whether candidates recognize patterns in binary arrays and convert them into simple mathematical counts.

What data structure is used in Ways to Split Array Into Good Subarrays?

The solution primarily uses basic array traversal with a few integer counters. No advanced data structures are required. The core idea relies on mathematical counting of gaps between elements in a binary array.

What is the time complexity of Ways to Split Array Into Good Subarrays?

The optimal solution runs in O(n) time because the array is scanned once to locate the positions of 1s and compute the gaps between them. Space complexity is O(1) since only a few counters and the previous index of 1 are stored.

Comments

Now write it yourselfClose this page and solve Ways to Split Array Into Good Subarrays in the editor, without looking.
Practise Ways to Split Array Into Good Subarrays