Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Program to find maximum number of non-overlapping subarrays with sum equals target using Python
Given an array of numbers and a target value, we need to find the maximum number of non-overlapping subarrays where each subarray's sum equals the target.
For example, if nums = [3,2,4,5,2,1,5] and target = 6, we can find two subarrays: [2,4] and [1,5], both with sum 6.
Approach Using Prefix Sum and Set
The key insight is to use prefix sums and track cumulative sums in a set. When we find a valid subarray, we reset our tracking to avoid overlaps.
Algorithm Steps
Initialize a set
twith element 0 (for subarrays starting from index 0)Track running sum
tempand answer countansFor each number, check if
(current_sum - target)exists in our setIf found, we have a valid subarray − increment count and reset tracking
Otherwise, add current sum to our set
Example
def solve(nums, target):
t = set([0]) # Track prefix sums
temp = 0 # Running sum
ans = 0 # Count of subarrays
for i in nums:
temp += i
prev = temp - target
if prev in t:
# Found a subarray with sum = target
ans += 1
t = set([temp]) # Reset to avoid overlap
else:
t.add(temp)
return ans
# Test with example
nums = [3, 2, 4, 5, 2, 1, 5]
target = 6
result = solve(nums, target)
print(f"Maximum non-overlapping subarrays: {result}")
# Show the subarrays for clarity
print("Subarrays found: [2,4] and [1,5]")
Maximum non-overlapping subarrays: 2 Subarrays found: [2,4] and [1,5]
How It Works
The algorithm works by maintaining prefix sums. If current_sum - target exists in our set, it means there's a subarray ending at the current position with sum equal to target.
When we find such a subarray, we reset our set to contain only the current sum, ensuring no overlap with future subarrays.
Step-by-Step Trace
def solve_with_trace(nums, target):
t = set([0])
temp = 0
ans = 0
for i, num in enumerate(nums):
temp += num
prev = temp - target
print(f"Index {i}: num={num}, temp={temp}, prev={prev}, set={t}")
if prev in t:
ans += 1
t = set([temp])
print(f" Found subarray! Count: {ans}, Reset set to {t}")
else:
t.add(temp)
print(f" Added {temp} to set: {t}")
return ans
nums = [3, 2, 4, 5, 2, 1, 5]
target = 6
solve_with_trace(nums, target)
Index 0: num=3, temp=3, prev=-3, set={0}
Added 3 to set: {0, 3}
Index 1: num=2, temp=5, prev=-1, set={0, 3}
Added 5 to set: {0, 3, 5}
Index 2: num=4, temp=9, prev=3, set={0, 3, 5}
Found subarray! Count: 1, Reset set to {9}
Index 3: num=5, temp=14, prev=8, set={9}
Added 14 to set: {9, 14}
Index 4: num=2, temp=16, prev=10, set={9, 14}
Added 16 to set: {16, 9, 14}
Index 5: num=1, temp=17, prev=11, set={16, 9, 14}
Added 17 to set: {16, 17, 9, 14}
Index 6: num=5, temp=22, prev=16, set={16, 17, 9, 14}
Found subarray! Count: 2, Reset set to {22}
Time and Space Complexity
| Aspect | Complexity | Explanation |
|---|---|---|
| Time | O(n) | Single pass through array |
| Space | O(n) | Set can store up to n prefix sums |
Conclusion
This greedy approach using prefix sums efficiently finds the maximum number of non-overlapping subarrays with target sum. The key insight is resetting our tracking set when a valid subarray is found to ensure non-overlapping results.
