Maximum Number of Non-Overlapping Subarrays With Sum Equals Target

medium prefix sum hash table greedy

Problem

Given an array nums and an integer target, return the maximum number of non-empty, non-overlapping subarrays such that the sum of each subarray equals target. Two subarrays are non-overlapping when they share no index.

Inputnums = [1,1,1,1,1], target = 2
Output2
Pick [1,1] at indices 0–1 and [1,1] at indices 3–4, each summing to 2. They don't overlap, so the answer is 2.

def maxNonOverlapping(nums, target):
    seen = {0}          # prefix sums seen since the last cut
    prefix = 0          # running prefix sum within the current block
    count = 0
    for x in nums:
        prefix += x
        if prefix - target in seen:
            # a subarray ending here sums to target -> take it greedily
            count += 1
            seen = {0}   # cut: start a fresh block after this index
            prefix = 0
        else:
            seen.add(prefix)
    return count
function maxNonOverlapping(nums, target) {
  const seen = new Set([0]); // prefix sums since the last cut
  let prefix = 0;            // running prefix within the current block
  let count = 0;
  for (const x of nums) {
    prefix += x;
    if (seen.has(prefix - target)) {
      // subarray ending here sums to target -> take it greedily
      count++;
      seen.clear();
      seen.add(0);           // cut: fresh block after this index
      prefix = 0;
    } else {
      seen.add(prefix);
    }
  }
  return count;
}
int maxNonOverlapping(int[] nums, int target) {
    Set<Integer> seen = new HashSet<>();
    seen.add(0);            // prefix sums since the last cut
    int prefix = 0;        // running prefix within the current block
    int count = 0;
    for (int x : nums) {
        prefix += x;
        if (seen.contains(prefix - target)) {
            // subarray ending here sums to target -> take greedily
            count++;
            seen.clear();
            seen.add(0);   // cut: fresh block after this index
            prefix = 0;
        } else {
            seen.add(prefix);
        }
    }
    return count;
}
int maxNonOverlapping(vector<int>& nums, int target) {
    unordered_set<int> seen{0}; // prefix sums since the last cut
    int prefix = 0;            // running prefix within the block
    int count = 0;
    for (int x : nums) {
        prefix += x;
        if (seen.count(prefix - target)) {
            // subarray ending here sums to target -> take greedily
            count++;
            seen.clear();
            seen.insert(0);    // cut: fresh block after this index
            prefix = 0;
        } else {
            seen.insert(prefix);
        }
    }
    return count;
}
Time: O(n) Space: O(n)