Binary Subarrays With Sum

Updated on 15 May, 2025
Binary Subarrays With Sum header image

Problem Statement

In the given problem, you are provided with a binary array named nums and an integer goal. The main task is to determine the number of contiguous subarrays within nums that sum up to exactly the goal. A subarray is defined as a continuous subset of the array, and it must be non-empty. This type of problem is commonly associated with array manipulation and presents an opportunity to explore various techniques to calculate subarray sums efficiently.

Examples

Example 1

Input:

nums = [1,0,1,0,1], goal = 2

Output:

4

Explanation:

The 4 subarrays are bolded and underlined below:

[1,0,1,0,1] [1,0,1,0,1] [1,0,1,0,1] [1,0,1,0,1]

Example 2

Input:

nums = [0,0,0,0,0], goal = 0

Output:

15

Constraints

  • 1 <= nums.length <= 3 * 104
  • nums[i] is either 0 or 1.
  • 0 <= goal <= nums.length

Approach and Intuition

Understanding the problem with the examples given can help determine an optimal approach to the solution:

  1. Utilizing the Prefix Sum Technique:

    • The prefix sum array helps in quickly calculating the sum of any subarray.
    • For any subarray nums[i:j+], the sum can be retrieved by prefix[j+1] - prefix[i], where prefix[k] is the sum of elements from the start of nums up to but not including index k.
    • The challenge then reduces to finding pairs of indices (i, j) such that prefix[j+1] - prefix[i] = goal.
  2. Using a hashmap to optimize:

    • While iterating over the array, you can maintain a running sum and use a hashmap to store the frequency of each sum encountered up to the current point.
    • For each element in nums, update the running sum. Check how many times (running sum - goal) has appeared in the hashmap because it indicates the number of subarrays ending at the current index that have the required goal.
    • This method ensures that we only pass through the array once, maintaining efficiency.
  3. Breaking down the examples:

    • Example 1: In the array [1,0,1,0,1] with goal = 2:
      • The possible subarrays achieving this sum are: [1,0,1], [1,0,1], [0,1,0,1], [1,0,1]. Each of these sequences sum up to 2, thus giving 4 as the output.
    • Example 2: In the array [0,0,0,0,0] with a goal = 0:
      • Here, several single-element subarrays and multi-element subarrays sum to 0, totaling up to 15 subarrays.

Through the hashmap and prefix sum technique, it's feasible to solve the problem with a linear time complexity relative to the size of nums, ensuring efficient processing even for larger arrays. This approach leverages the characteristics of subarray sums and hash-based storage for past computed sums to streamline the search for subarrays that meet the desired goal.

Solutions

  • C++
  • Java
  • Python
cpp
class Solution {
public:
    int countTargetSubarrays(vector<int>& arr, int target) {
        int left = 0;
        int zeroCount = 0;
        int sum = 0;
        int result = 0;
        
        for (int right = 0; right < arr.size(); ++right) {
            sum += arr[right];
            
            while (left < right && (arr[left] == 0 || sum > target)) {
                if (arr[left] == 1) {
                    zeroCount = 0;
                } else {
                    zeroCount += 1;
                }
                
                sum -= arr[left];
                left += 1;
            }
            
            if (sum == target) {
                result += 1 + zeroCount;
            }
        }
        
        return result;
    }
};

The provided C++ code defines a method countTargetSubarrays within a Solution class that counts subarrays whose elements sum up to a given target value. This solution utilizes a two-pointer approach with some additional logic to incorporate cases where zeroes are involved, which might extend valid subarrays without changing the sum.

  • Initially, left, zeroCount, sum, and result are initialized. These track the left boundary of the subarray, count of zero entries, running total of array values, and the count of valid subarrays, respectively.
  • Loop through each element in the array with right pointer incrementing to expand the subarray.
  • Add the value of the current element to sum.
  • Inside a while loop, adjust the left pointer to shrink the subarray until its sum equals or is less than target. During this while loop:
    • If a non-zero is encountered, zero count is reset.
    • If zero is encountered, it is counted since it doesn't affect the sum.
    • The sum is adjusted by subtracting the value at the left pointer, and left is incremented.
  • If the sum equals target, increase result by 1 for the subarray identified from left to right, plus any extra subarrays that can be formed by prefixing zeroes counted by zeroCount.
  • The function returns result, the total count of valid subarrays that sum up to target.

This algorithm efficiently processes the array in linear time by dynamically adjusting the window of considered subarray using the two pointers and leveraging zero values to count additional valid combinations that form the target sum. Such an approach handles the array linearly, avoiding unnecessary recomputation for overlapping subarrays.

java
class Solution {
    public int countSubarraysWithSum(int[] input, int target) {
        int leftIndex = 0;
        int zeroCount = 0;
        int cumulativeSum = 0;
        int matchCount = 0;

        for (int rightIndex = 0; rightIndex < input.length; rightIndex++) {
            cumulativeSum += input[rightIndex];

            while (leftIndex < rightIndex && (input[leftIndex] == 0 || cumulativeSum > target)) {
                if (input[leftIndex] == 0) {
                    zeroCount++;
                } else {
                    zeroCount = 0;
                }

                cumulativeSum -= input[leftIndex];
                leftIndex++;
            }

            if (cumulativeSum == target) {
                matchCount += 1 + zeroCount;
            }
        }

        return matchCount;
    }
}

The Java program provided aims to solve the problem of counting the number of subarrays in an array that sum up to a specific target number. Here's a concise recap of how the logic in this code works:

  • Define variables to track the left and right indices (leftIndex, rightIndex), the cumulative sum of elements (cumulativeSum), zeros count between occurrences of necessary sums (zeroCount), and the total count of matching subarrays (matchCount).
  • Use a single for-loop to iterate through the given array from the beginning (rightIndex from 0 to array length).
  • Add the current element value to cumulativeSum.
  • If cumulativeSum exceeds the target and iterator leftIndex has not overtaken rightIndex, adjust the leftIndex. If the left-most element is zero, modify zeroCount accordingly; otherwise, reset zeroCount.
  • Each time cumulativeSum matches the target, increment matchCount by 1 plus any zeroCount which accounts for zero-filled gaps between numbers contributing to the sum.
  • Continue until all elements have been processed.
  • Ultimately, return matchCount which represents the total number of subarrays that meet the target sum criterion.

Ensure the input array and target sum are correctly defined before invoking this method to avoid any runtime errors or logical issues. This solution efficiently manages both the case where elements contribute directly to the desired sum and the adjustments needed when zero elements exist between contributing numbers, thus providing a comprehensive approach to the subarray sum problem.

python
class Solution:
    def countSubarraysWithSum(self, elements: List[int], target: int) -> int:
        left_index = 0
        num_zeros = 0
        sum_of_elements = 0
        count_of_subarrays = 0
        
        # Iterate through array elements with an ending index
        for right_index, element in enumerate(elements):
            # Increment the sum with current element
            sum_of_elements += element
            
            # Adjust the window's start index and conditions
            while left_index < right_index and (elements[left_index] == 0 or sum_of_elements > target):
                if elements[left_index] == 1:
                    num_zeros = 0
                else:
                    num_zeros += 1
                
                sum_of_elements -= elements[left_index]
                left_index += 1
                
            # If current window's sum equals target, count possible subarrays
            if sum_of_elements == target:
                count_of_subarrays += 1 + num_zeros
                
        return count_of_subarrays

The problem "Binary Subarrays With Sum" involves finding the number of contiguous subarrays in a binary array that sum up to a specific target value. The provided Python solution employs a sliding window approach to efficiently handle this problem.

  • Begin with initializing your variables: left_index to keep track of the left boundary of the sliding window, num_zeros to count the number of extraneous zeros in the current window, sum_of_elements to accumulate the sum of elements in the current window, and count_of_subarrays to count the subarrays meeting the target sum.

  • Loop through each element in the input list using an index and the value with enumerate(). Increment the sum_of_elements by the current element each time.

  • Inside the loop, adjust the window's start index (left_index) if it either contains a zero that can be excluded or if the sum_of_elements exceeds the target. Track the number of zeros that were skipped as they might form new subarrays meeting the target when included with other elements.

  • Check after every adjustment whether the sum_of_elements matches the target and, if it does, increase the count_of_subarrays by one plus the number of extraneous zeros thus accounting for all subarrays formed with the current right boundary.

  • Return the total count of such subarrays at the end of the loop.

This approach has an overall time complexity that is more efficient than brute forcing each possible subarray, particularly for larger arrays, as it does not recompute the sum for overlapping parts of the array due to the sliding window technique.

Comments

No comments yet.