Count maximum non-overlapping subarrays with given sum
Given an array arr[] consisting of N integers and an integer target, the task is to find the maximum number of non-empty non-overlapping subarrays such that the sum of array elements in each subarray is equal to the target.
Examples:
Input: arr[] = {2, -1, 4, 3, 6, 4, 5, 1}, target = 6
Output: 3
Explanation:
Subarrays {-1, 4, 3}, {6} and {5, 1} have sum equal to target(= 6).Input: arr[] = {2, 2, 2, 2, 2}, target = 4
Output: 2
Approach: To obtain the smallest non-overlapping subarrays with the sum target, the target is to use the Prefix Sum technique. Follow the steps below to solve the problem:
- Store all the sums calculated so far in a Map mp with key as the sum of the prefix till that index and value as the ending index of the subarray with that sum.
- If the prefix-sum till index i, say sum, is equal to target, check if sum – target exists in the Map or not.
- If sum – target exists in Map and mp[sum – target] = idx, it means that the subarray from [idx + 1, i] has sum equal to target.
- Now for non-overlapping subarrays, maintain an additional variable availIdx(initially set to -1), and take the subarray from [idx + 1, i] only when mp[sum – target] ≥ availIdx.
- Whenever such a subarray is found, increment the answer and change the value of availIdx to the current index.
- Also, for non-overlapping subarrays, it is always beneficial to greedily take subarrays as small as possible. So, for every prefix-sum found, update its index in the Map, even if it already exists.
- Print the value of count after completing the above steps.
Below is the implementation of the above approach:
C++
// C++ program for the above approach #include <bits/stdc++.h> using namespace std; // Function to count maximum number // of non-overlapping subarrays with // sum equals to the target int maximumSubarrays( int arr[], int N, int target) { // Stores the final count int ans = 0; // Next subarray should start // from index >= availIdx int availIdx = -1; // Tracks the prefix sum int cur_sum = 0; // Map to store the prefix sum // for respective indices unordered_map< int , int > mp; mp[0] = -1; for ( int i = 0; i < N; i++) { cur_sum += arr[i]; // Check if cur_sum - target is // present in the array or not if (mp.find(cur_sum - target) != mp.end() && mp[cur_sum - target] >= availIdx) { ans++; availIdx = i; } // Update the index of // current prefix sum mp[cur_sum] = i; } // Return the count of subarrays return ans; } // Driver Code int main() { // Given array arr[] int arr[] = { 2, -1, 4, 3, 6, 4, 5, 1 }; int N = sizeof (arr) / sizeof (arr[0]); // Given sum target int target = 6; // Function Call cout << maximumSubarrays(arr, N, target); return 0; } |
Java
// Java program for the above approach import java.util.*; class GFG{ // Function to count maximum number // of non-overlapping subarrays with // sum equals to the target static int maximumSubarrays( int arr[], int N, int target) { // Stores the final count int ans = 0 ; // Next subarray should start // from index >= availIdx int availIdx = - 1 ; // Tracks the prefix sum int cur_sum = 0 ; // Map to store the prefix sum // for respective indices HashMap<Integer, Integer> mp = new HashMap<Integer, Integer>(); mp.put( 0 , 1 ); for ( int i = 0 ; i < N; i++) { cur_sum += arr[i]; // Check if cur_sum - target is // present in the array or not if (mp.containsKey(cur_sum - target) && mp.get(cur_sum - target) >= availIdx) { ans++; availIdx = i; } // Update the index of // current prefix sum mp.put(cur_sum, i); } // Return the count of subarrays return ans; } // Driver Code public static void main(String[] args) { // Given array arr[] int arr[] = { 2 , - 1 , 4 , 3 , 6 , 4 , 5 , 1 }; int N = arr.length; // Given sum target int target = 6 ; // Function call System.out.print(maximumSubarrays(arr, N, target)); } } // This code is contributed by Amit Katiyar |
Python3
# Python3 program for the above approach # Function to count maximum number # of non-overlapping subarrays with # sum equals to the target def maximumSubarrays(arr, N, target): # Stores the final count ans = 0 # Next subarray should start # from index >= availIdx availIdx = - 1 # Tracks the prefix sum cur_sum = 0 # Map to store the prefix sum # for respective indices mp = {} mp[ 0 ] = - 1 for i in range (N): cur_sum + = arr[i] # Check if cur_sum - target is # present in the array or not if ((cur_sum - target) in mp and mp[cur_sum - target] > = availIdx): ans + = 1 availIdx = i # Update the index of # current prefix sum mp[cur_sum] = i # Return the count of subarrays return ans # Driver Code if __name__ = = '__main__' : # Given array arr[] arr = [ 2 , - 1 , 4 , 3 , 6 , 4 , 5 , 1 ] N = len (arr) # Given sum target target = 6 # Function call print (maximumSubarrays(arr, N, target)) # This code is contributed by mohit kumar 29 |
C#
// C# program for the above approach using System; using System.Collections.Generic; class GFG{ // Function to count maximum number // of non-overlapping subarrays with // sum equals to the target static int maximumSubarrays( int []arr, int N, int target) { // Stores the readonly count int ans = 0; // Next subarray should start // from index >= availIdx int availIdx = -1; // Tracks the prefix sum int cur_sum = 0; // Map to store the prefix sum // for respective indices Dictionary< int , int > mp = new Dictionary< int , int >(); mp.Add(0, 1); for ( int i = 0; i < N; i++) { cur_sum += arr[i]; // Check if cur_sum - target is // present in the array or not if (mp.ContainsKey(cur_sum - target) && mp[cur_sum - target] >= availIdx) { ans++; availIdx = i; } // Update the index of // current prefix sum if (mp.ContainsKey(cur_sum)) mp[cur_sum] = i; else mp.Add(cur_sum, i); } // Return the count of subarrays return ans; } // Driver Code public static void Main(String[] args) { // Given array []arr int []arr = {2, -1, 4, 3, 6, 4, 5, 1}; int N = arr.Length; // Given sum target int target = 6; // Function call Console.Write(maximumSubarrays(arr, N, target)); } } // This code is contributed by Princi Singh |
Javascript
<script> // JavaScript program for the above approach // Function to count maximum number // of non-overlapping subarrays with // sum equals to the target function maximumSubarrays(arr, N, target) { // Stores the final count var ans = 0; // Next subarray should start // from index >= availIdx var availIdx = -1; // Tracks the prefix sum var cur_sum = 0; // Map to store the prefix sum // for respective indices var mp = new Map(); mp.set(0, 1); for ( var i = 0; i < N; i++) { cur_sum += arr[i]; // Check if cur_sum - target is // present in the array or not if (mp.has(cur_sum - target) && mp.get(cur_sum - target) >= availIdx) { ans++; availIdx = i; } // Update the index of // current prefix sum mp.set(cur_sum , i); } // Return the count of subarrays return ans; } // Driver Code // Given array arr[] var arr = [2, -1, 4, 3, 6, 4, 5, 1]; var N = arr.length; // Given sum target var target = 6; // Function Call document.write( maximumSubarrays(arr, N, target)); </script> |
Output:
3
Time Complexity: O(N)
Auxiliary Space: O(N)
Please Login to comment...