Count subarrays with non-zero sum in the given Array
Last Updated :
13 Aug, 2021
Given an array arr[] of size N, the task is to count the total number of subarrays for the given array arr[] which have a non-zero-sum.
Examples:
Input: arr[] = {-2, 2, -3}
Output: 4
Explanation:
The subarrays with non zero sum are: [-2], [2], [2, -3], [-3]. All possible subarray of the given input array are [-2], [2], [-3], [2, -2], [2, -3], [-2, 2, -3]. Out of these [2, -2] is not included in the count because 2+(-2) = 0 and [-2, 2, -3] is not selected because one the subarray [2, -2] of this array has a zero sum of elements.
Input: arr[] = {1, 3, -2, 4, -1}
Output: 15
Explanation:
There are 15 subarray for the given array {1, 3, -2, 4, -1} which has a non zero sum.
Approach:
The main idea to solve the above question is to use the Prefix Sum Array and Map Data Structure.
- First, build the Prefix sum array of the given array and use the below formula to check if the subarray has 0 sum of elements.
Sum of Subarray[L, R] = Prefix[R] – Prefix[L – 1]. So, If Sum of Subarray[L, R] = 0
Then, Prefix[R] – Prefix[L – 1] = 0. Hence, Prefix[R] = Prefix[L – 1]
- Now, iterate from 1 to N and keep a Hash table for storing the index of the previous occurrence of the element and a variable let’s say last, and initialize it to 0.
- Check if Prefix[i] is already present in the Hash or not. If yes then, update last as last = max(last, hash[Prefix[i]] + 1). Otherwise, Add i – last to the answer and update the Hash table.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
vector< int > PrefixSumArray( int arr[], int n)
{
vector< int > prefix(n);
prefix[0] = arr[0];
for ( int i = 1; i < n; i++)
prefix[i] = prefix[i - 1] + arr[i];
return prefix;
}
int CountSubarray( int arr[], int n)
{
vector< int > Prefix(n);
Prefix = PrefixSumArray(arr, n);
int last = 0, ans = 0;
map< int , int > Hash;
Hash[0] = -1;
for ( int i = 0; i <= n; i++) {
if (Hash.count(Prefix[i]))
last = max(last, Hash[Prefix[i]] + 1);
ans += max(0, i - last);
Hash[Prefix[i]] = i;
}
return ans;
}
int main()
{
int arr[] = { 1, 3, -2, 4, -1 };
int N = sizeof (arr) / sizeof (arr[0]);
cout << CountSubarray(arr, N);
}
|
Java
import java.util.*;
class GFG{
static int [] PrefixSumArray( int arr[], int n)
{
int []prefix = new int [n];
prefix[ 0 ] = arr[ 0 ];
for ( int i = 1 ; i < n; i++)
prefix[i] = prefix[i - 1 ] + arr[i];
return prefix;
}
static int CountSubarray( int arr[], int n)
{
int []Prefix = new int [n];
Prefix = PrefixSumArray(arr, n);
int last = 0 , ans = 0 ;
HashMap<Integer,
Integer> Hash = new HashMap<Integer,
Integer>();
Hash.put( 0 , - 1 );
for ( int i = 0 ; i <= n; i++)
{
if (i < n && Hash.containsKey(Prefix[i]))
last = Math.max(last,
Hash.get(Prefix[i]) + 1 );
ans += Math.max( 0 , i - last);
if (i < n)
Hash.put(Prefix[i], i);
}
return ans;
}
public static void main(String[] args)
{
int arr[] = { 1 , 3 , - 2 , 4 , - 1 };
int N = arr.length;
System.out.print(CountSubarray(arr, N));
}
}
|
Python3
def PrefixSumArray(arr, n):
prefix = [ 0 ] * (n + 1 );
prefix[ 0 ] = arr[ 0 ];
for i in range ( 1 , n):
prefix[i] = prefix[i - 1 ] + arr[i];
return prefix;
def CountSubarray(arr, n):
Prefix = [ 0 ] * (n + 1 );
Prefix = PrefixSumArray(arr, n);
last = 0 ; ans = 0 ;
Hash = {};
Hash [ 0 ] = - 1 ;
for i in range (n + 1 ):
if (Prefix[i] in Hash ):
last = max (last, Hash [Prefix[i]] + 1 );
ans + = max ( 0 , i - last);
Hash [Prefix[i]] = i;
return ans;
if __name__ = = "__main__" :
arr = [ 1 , 3 , - 2 , 4 , - 1 ];
N = len (arr);
print (CountSubarray(arr, N));
|
C#
using System;
using System.Collections.Generic;
class GFG{
static int [] PrefixSumArray( int []arr, int n)
{
int []prefix = new int [n];
prefix[0] = arr[0];
for ( int i = 1; i < n; i++)
prefix[i] = prefix[i - 1] + arr[i];
return prefix;
}
static int CountSubarray( int []arr, int n)
{
int []Prefix = new int [n];
Prefix = PrefixSumArray(arr, n);
int last = 0, ans = 0;
Dictionary< int ,
int > Hash = new Dictionary< int ,
int >();
Hash.Add(0, -1);
for ( int i = 0; i <= n; i++)
{
if (i < n && Hash.ContainsKey(Prefix[i]))
last = Math.Max(last,
Hash[Prefix[i]] + 1);
ans += Math.Max(0, i - last);
if (i < n)
Hash.Add(Prefix[i], i);
}
return ans;
}
public static void Main(String[] args)
{
int []arr = {1, 3, -2, 4, -1};
int N = arr.Length;
Console.Write(CountSubarray(arr, N));
}
}
|
Javascript
<script>
function PrefixSumArray(arr, n)
{
let prefix = Array.from({length: n}, (_, i) => 0);
prefix[0] = arr[0];
for (let i = 1; i < n; i++)
prefix[i] = prefix[i - 1] + arr[i];
return prefix;
}
function CountSubarray(arr, n)
{
let Prefix = Array.from({length: n}, (_, i) => 0);
Prefix = PrefixSumArray(arr, n);
let last = 0, ans = 0;
let Hash = new Map();
Hash.set(0, -1);
for (let i = 0; i <= n; i++)
{
if (i < n && Hash.has(Prefix[i]))
last = Math.max(last,
Hash.get(Prefix[i]) + 1);
ans += Math.max(0, i - last);
if (i < n)
Hash.set(Prefix[i], i);
}
return ans;
}
let arr = [ 1, 3, -2, 4, -1 ];
let N = arr.length;
document.write(CountSubarray(arr, N));
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(N)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...