Given an unsorted array of integers, find the number of subarrays having a sum exactly equal to a given number k.
Examples:
Input : arr[] = {10, 2, -2, -20, 10}, k = -10
Output : 3
Explanation: Subarrays: arr[0…3], arr[1…4], arr[3..4] have a sum exactly equal to -10.
Input : arr[] = {9, 4, 20, 3, 10, 5}, k = 33
Output : 2
Explanation: Subarrays : arr[0…2], arr[2…4] have a sum exactly equal to 33.
Naive Solution: A simple solution is to traverse all the subarrays and calculate their sum. If the sum is equal to the required sum, then increment the count of subarrays. Print final count of subarray.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int main()
{
int arr[] = {10, 2, -2, -20, 10};
int k = -10;
int n = sizeof (arr) / sizeof (arr[0]);
int res = 0;
for ( int i = 0; i < n; i++)
{
int sum = 0;
for ( int j = i; j < n; j++)
{
sum += arr[j];
if (sum == k)
res++;
}
}
cout << (res) << endl;
}
|
C
#include <stdio.h>
int main()
{
int arr[] = { 10, 2, -2, -20, 10 };
int k = -10;
int n = sizeof (arr) / sizeof (arr[0]);
int res = 0;
for ( int i = 0; i < n; i++) {
int sum = 0;
for ( int j = i; j < n; j++)
{
sum += arr[j];
if (sum == k)
res++;
}
}
printf ( "%d\n" , res);
}
|
Java
import java.util.*;
class Solution {
public static void main(String[] args)
{
int arr[] = { 10 , 2 , - 2 , - 20 , 10 };
int k = - 10 ;
int n = arr.length;
int res = 0 ;
for ( int i = 0 ; i < n; i++) {
int sum = 0 ;
for ( int j = i; j < n; j++) {
sum += arr[j];
if (sum == k)
res++;
}
}
System.out.println(res);
}
}
|
Python3
def count_all_subarrys(arr, n):
res = 0
for i in range (n):
summ = 0
for j in range (i, n):
summ + = arr[j]
if summ = = k:
res + = 1
return res
if __name__ = = "__main__" :
arr = [ 10 , 2 , - 2 , - 20 , 10 ]
n = len (arr)
k = - 10
print (count_all_subarrys(arr, n))
|
C#
using System;
using System.Collections.Generic;
class GFG {
static void Main() {
int [] arr = {10, 2, -2, -20, 10};
int k = -10;
int n = arr.Length;
int res = 0;
for ( int i = 0; i < n; i++)
{
int sum = 0;
for ( int j = i; j < n; j++)
{
sum += arr[j];
if (sum == k)
res++;
}
}
Console.WriteLine(res);
}
}
|
Javascript
<script>
let arr = [ 10, 2, -2, -20, 10 ];
let k = -10;
let n = arr.length;
let res = 0;
for (let i = 0; i < n; i++)
{
let sum = 0;
for (let j = i; j < n; j++)
{
sum += arr[j];
if (sum == k)
res++;
}
}
document.write(res);
</script>
|
Time Complexity : O(n2)
Auxiliary Space: O(1)
Efficient Solution :
An efficient solution is while traversing the array, storing sum so far in currsum. Also, maintain the count of different values of currsum in a map. If the value of currsum is equal to the desired sum at any instance increment count of subarrays by one.
The value of currsum exceeds the desired sum by currsum – sum. If this value is removed from currsum then the desired sum can be obtained. From the map, find the number of subarrays previously found having sum equal to currsum-sum. Excluding all those subarrays from the current subarray, gives new subarrays having the desired sum.
So increase count by the number of such subarrays. Note that when currsum is equal to the desired sum then also check the number of subarrays previously having a sum equal to 0. Excluding those subarrays from the current subarray gives new subarrays having the desired sum. Increase the count by the number of subarrays having sum 0 in that case.
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
int findSubarraySum( int arr[], int n, int sum)
{
unordered_map< int , int > prevSum;
int res = 0;
int currSum = 0;
for ( int i = 0; i < n; i++) {
currSum += arr[i];
if (currSum == sum)
res++;
if (prevSum.find(currSum - sum) != prevSum.end())
res += (prevSum[currSum - sum]);
prevSum[currSum]++;
}
return res;
}
int main()
{
int arr[] = { 10, 2, -2, -20, 10 };
int sum = -10;
int n = sizeof (arr) / sizeof (arr[0]);
cout << findSubarraySum(arr, n, sum);
return 0;
}
|
Java
import java.util.HashMap;
import java.util.Map;
public class GfG {
static int findSubarraySum( int arr[], int n, int sum)
{
HashMap<Integer, Integer> prevSum = new HashMap<>();
prevSum.put( 0 , 1 );
int res = 0 ;
int currSum = 0 ;
for ( int i = 0 ; i < n; i++) {
currSum += arr[i];
int removeSum=currSum-sum;
if (prevSum.containsKey(removeSum))
res += prevSum.get(removeSum);
prevSum.put(currSum,prevSum.getOrDefault(currSum, 0 )+ 1 );
}
return res;
}
public static void main(String[] args)
{
int arr[] = { 10 , 2 , - 2 , - 20 , 10 };
int sum = - 10 ;
int n = arr.length;
System.out.println(findSubarraySum(arr, n, sum));
}
}
|
Python3
from collections import defaultdict
def findSubarraySum(arr, n, Sum ):
prevSum = defaultdict( lambda : 0 )
res = 0
currsum = 0
for i in range ( 0 , n):
currsum + = arr[i]
if currsum = = Sum :
res + = 1
if (currsum - Sum ) in prevSum:
res + = prevSum[currsum - Sum ]
prevSum[currsum] + = 1
return res
if __name__ = = "__main__" :
arr = [ 10 , 2 , - 2 , - 20 , 10 ]
Sum = - 10
n = len (arr)
print (findSubarraySum(arr, n, Sum ))
|
C#
using System;
using System.Collections.Generic;
class GFG {
public static int findSubarraySum( int [] arr,
int n, int sum)
{
Dictionary< int , int > prevSum = new Dictionary< int , int >();
int res = 0;
int currsum = 0;
for ( int i = 0; i < n; i++) {
currsum += arr[i];
if (currsum == sum)
res++;
if (prevSum.ContainsKey(currsum - sum))
res += prevSum[currsum - sum];
if (!prevSum.ContainsKey(currsum))
prevSum.Add(currsum, 1);
else {
int count = prevSum[currsum];
prevSum[currsum] = count + 1;
}
}
return res;
}
public static void Main()
{
int [] arr = { 10, 2, -2, -20, 10 };
int sum = -10;
int n = arr.Length;
Console.Write(findSubarraySum(arr, n, sum));
}
}
|
Javascript
<script>
function findSubarraySum(arr,n,sum)
{
let prevSum = new Map();
let res = 0;
let currsum = 0;
for (let i = 0; i < n; i++)
{
currsum += arr[i];
if (currsum == sum)
res++;
if (prevSum.has(currsum - sum))
res += prevSum.get(currsum - sum);
let count = prevSum.get(currsum);
if (count == null )
prevSum.set(currsum, 1);
else
prevSum.set(currsum, count + 1);
}
return res;
}
let arr = [10, 2, -2, -20, 10];
let sum = -10;
let n = arr.length;
document.write(findSubarraySum(arr, n, sum));
</script>
|
Time Complexity: O(n)
Auxiliary Space: O(n)
This article is contributed by Aarti_Rathi. If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.