Count subarrays with equal number of 1’s and 0’s
Last Updated :
29 Nov, 2023
Given an array arr[] of size n containing 0 and 1 only. The problem is to count the subarrays having an equal number of 0’s and 1’s.
Examples:
Input: arr[] = {1, 0, 0, 1, 0, 1, 1}
Output: 8
Explanation: The index range for the 8 sub-arrays are: (0, 1), (2, 3), (0, 3), (3, 4), (4, 5)(2, 5), (0, 5), (1, 6)
Input: arr = { 1, 0, 0, 1, 1, 0, 0, 1}
Output: 12
Count subarrays with equal number of 1’s and 0’s using Frequency Counting:
The problem is closely related to the Largest subarray with an equal number of 0’s and 1’s
Follow the steps below to implement the above idea:
- Consider all 0’s in arr[] as -1.
- Create a hash table that holds the count of each sum[i] value, where sum[i] = sum(arr[0]+..+arr[i]), for i = 0 to n-1.
- Now start calculating the cumulative sum and then we get an incremental count of 1 for that sum represented as an index in the hash table. Arrays of each pair of positions with the same value in the cumulative sum constitute a continuous range with an equal number of 1’s and 0’s.
- Now traverse the hash table and get the frequency of each element in the hash table. Let frequency be denoted as freq. For each freq > 1 we can choose any two pairs of indices of a sub-array by (freq * (freq – 1)) / 2 number of ways. Do the same for all freq and sum up the result will be the number of all possible sub-arrays containing the equal number of 1’s and 0’s.
- Also, add freq of the sum of 0 to the hash table for the final result.
Explanation:
Considering all 0’s as -1. if sum[i] == sum[j], where sum[i] = sum(arr[0]+..+arr[i]) and sum[j] = sum(arr[0]+..+arr[j]) and ‘i’ is less than ‘j’, then sum(arr[i+1]+..+arr[j]) must be 0. It can only be 0 if arr(i+1, .., j) contains an equal number of 1’s and 0’s.
Follow the steps below to implement the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int countSubarrWithEqualZeroAndOne( int arr[], int n)
{
unordered_map< int , int > um;
int curr_sum = 0;
for ( int i = 0; i < n; i++) {
curr_sum += (arr[i] == 0) ? -1 : arr[i];
um[curr_sum]++;
}
int count = 0;
for ( auto itr = um.begin(); itr != um.end(); itr++) {
if (itr->second > 1)
count
+= ((itr->second * (itr->second - 1)) / 2);
}
if (um.find(0) != um.end())
count += um[0];
return count;
}
int main()
{
int arr[] = { 1, 0, 0, 1, 0, 1, 1 };
int n = sizeof (arr) / sizeof (arr[0]);
cout << "Count = "
<< countSubarrWithEqualZeroAndOne(arr, n);
return 0;
}
|
Java
import java.util.*;
class GFG {
static int countSubarrWithEqualZeroAndOne( int arr[],
int n)
{
Map<Integer, Integer> um = new HashMap<>();
int curr_sum = 0 ;
for ( int i = 0 ; i < n; i++) {
curr_sum += (arr[i] == 0 ) ? - 1 : arr[i];
um.put(curr_sum, um.get(curr_sum) == null
? 1
: um.get(curr_sum) + 1 );
}
int count = 0 ;
for (Map.Entry<Integer, Integer> itr :
um.entrySet()) {
if (itr.getValue() > 1 )
count += ((itr.getValue()
* (itr.getValue() - 1 ))
/ 2 );
}
if (um.containsKey( 0 ))
count += um.get( 0 );
return count;
}
public static void main(String[] args)
{
int arr[] = { 1 , 0 , 0 , 1 , 0 , 1 , 1 };
int n = arr.length;
System.out.println(
"Count = "
+ countSubarrWithEqualZeroAndOne(arr, n));
}
}
|
Python3
def countSubarrWithEqualZeroAndOne(arr, n):
um = dict ()
curr_sum = 0
for i in range (n):
curr_sum + = ( - 1 if (arr[i] = = 0 ) else arr[i])
if um.get(curr_sum):
um[curr_sum] + = 1
else :
um[curr_sum] = 1
count = 0
for itr in um:
if um[itr] > 1 :
count + = ((um[itr] * int (um[itr] - 1 )) / 2 )
if um.get( 0 ):
count + = um[ 0 ]
return int (count)
arr = [ 1 , 0 , 0 , 1 , 0 , 1 , 1 ]
n = len (arr)
print ( "Count =" ,
countSubarrWithEqualZeroAndOne(arr, n))
|
C#
using System;
using System.Collections.Generic;
class GFG {
static int countSubarrWithEqualZeroAndOne( int [] arr,
int n)
{
Dictionary< int , int > mp
= new Dictionary< int , int >();
int curr_sum = 0;
for ( int i = 0; i < n; i++) {
curr_sum += (arr[i] == 0) ? -1 : arr[i];
if (mp.ContainsKey(curr_sum)) {
var v = mp[curr_sum];
mp.Remove(curr_sum);
mp.Add(curr_sum, ++v);
}
else
mp.Add(curr_sum, 1);
}
int count = 0;
foreach (KeyValuePair< int , int > itr in mp)
{
if (itr.Value > 1)
count
+= ((itr.Value * (itr.Value - 1)) / 2);
}
if (mp.ContainsKey(0))
count += mp[0];
return count;
}
public static void Main(String[] args)
{
int [] arr = { 1, 0, 0, 1, 0, 1, 1 };
int n = arr.Length;
Console.WriteLine(
"Count = "
+ countSubarrWithEqualZeroAndOne(arr, n));
}
}
|
Javascript
<script>
function countSubarrWithEqualZeroAndOne(arr, n)
{
var um = new Map();
var curr_sum = 0;
for ( var i = 0; i < n; i++) {
curr_sum += (arr[i] == 0) ? -1 : arr[i];
if (um.has(curr_sum))
um.set(curr_sum, um.get(curr_sum)+1);
else
um.set(curr_sum, 1)
}
var count = 0;
um.forEach((value, key) => {
if (value > 1)
count += ((value * (value - 1)) / 2);
});
if (um.has(0))
count += um.get(0);
return count;
}
var arr = [1, 0, 0, 1, 0, 1, 1];
var n = arr.length;
document.write( "Count = "
+ countSubarrWithEqualZeroAndOne(arr, n));
</script>
|
PHP
<?php
function countSubarrWithEqualZeroAndOne( $arr , $n ) {
$um = array ();
$curr_sum = 0;
for ( $i = 0; $i < $n ; $i ++) {
$curr_sum += ( $arr [ $i ] == 0) ? -1 : $arr [ $i ];
$um [ $curr_sum ]++;
}
$count = 0;
foreach ( $um as $value ) {
if ( $value > 1) {
$count += (( $value * ( $value - 1)) / 2);
}
}
if ( array_key_exists (0, $um )) {
$count += $um [0];
}
return $count ;
}
$arr = array (1, 0, 0, 1, 0, 1, 1);
$n = count ( $arr );
echo "Count = " . countSubarrWithEqualZeroAndOne( $arr , $n );
?>
|
Time Complexity: O(N), where N is the length of the given array
Auxiliary Space: O(N).
Count subarrays with equal number of 1’s and 0’s using Map:
Follow the steps below for implementation:
- Create a map say mp.
- Iterate over the length of the given array
- Check if arr[i] == 0, then replace it with -1.
- Keep calculating the number into sum till ith index.
- If sum = 0, it implies the number of 0’s and 1’s are equal from arr[0]..arr[i]
- if mp[sum] exists then add “frequency-1” to count
- if the frequency of “sum” is zero then we initialize that frequency to 1, f it’s not 0, we increment it
- Finally, return the count.
Follow the steps below to implement the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int countSubarrWithEqualZeroAndOne( int arr[], int n)
{
unordered_map< int , int > mp;
int sum = 0;
int count = 0;
for ( int i = 0; i < n; i++) {
if (arr[i] == 0)
arr[i] = -1;
sum += arr[i];
if (sum == 0)
count++;
if (mp[sum])
count += mp[sum];
if (mp[sum] == 0)
mp[sum] = 1;
else
mp[sum]++;
}
return count;
}
int main()
{
int arr[] = { 1, 0, 0, 1, 0, 1, 1 };
int n = sizeof (arr) / sizeof (arr[0]);
cout << "count="
<< countSubarrWithEqualZeroAndOne(arr, n);
}
|
Java
import java.util.HashMap;
import java.util.Map;
public class Main {
static int countSubarrWithEqualZeroAndOne( int [] arr,
int n)
{
Map<Integer, Integer> myMap = new HashMap<>();
int sum = 0 ;
int count = 0 ;
for ( int i = 0 ; i < n; i++) {
if (arr[i] == 0 )
arr[i] = - 1 ;
sum += arr[i];
if (sum == 0 )
count++;
if (myMap.containsKey(sum))
count += myMap.get(sum);
if (!myMap.containsKey(sum))
myMap.put(sum, 1 );
else
myMap.put(sum, myMap.get(sum) + 1 );
}
return count;
}
public static void main(String[] args)
{
int arr[] = { 1 , 0 , 0 , 1 , 0 , 1 , 1 };
int n = arr.length;
System.out.println(
"Count = "
+ countSubarrWithEqualZeroAndOne(arr, n));
}
}
|
Python3
def countSubarrWithEqualZeroAndOne(arr, n):
mp = dict ()
Sum = 0
count = 0
for i in range (n):
if (arr[i] = = 0 ):
arr[i] = - 1
Sum + = arr[i]
if ( Sum = = 0 ):
count + = 1
if ( Sum in mp.keys()):
count + = mp[ Sum ]
mp[ Sum ] = mp.get( Sum , 0 ) + 1
return count
arr = [ 1 , 0 , 0 , 1 , 0 , 1 , 1 ]
n = len (arr)
print ( "count =" ,
countSubarrWithEqualZeroAndOne(arr, n))
|
C#
using System;
using System.Collections.Generic;
class GFG {
static int countSubarrWithEqualZeroAndOne( int [] arr,
int n)
{
Dictionary< int , int > myMap
= new Dictionary< int , int >();
int sum = 0;
int count = 0;
for ( int i = 0; i < n; i++) {
if (arr[i] == 0)
arr[i] = -1;
sum += arr[i];
if (sum == 0)
count++;
if (myMap.ContainsKey(sum))
count += myMap[sum];
if (!myMap.ContainsKey(sum))
myMap.Add(sum, 1);
else {
var v = myMap[sum] + 1;
myMap.Remove(sum);
myMap.Add(sum, v);
}
}
return count;
}
public static void Main(String[] args)
{
int [] arr = { 1, 0, 0, 1, 0, 1, 1 };
int n = arr.Length;
Console.WriteLine(
"Count = "
+ countSubarrWithEqualZeroAndOne(arr, n));
}
}
|
Javascript
<script>
function countSubarrWithEqualZeroAndOne(arr, n)
{
var mp = new Map();
var sum = 0;
let count = 0;
for ( var i = 0; i < n; i++) {
if (arr[i] == 0)
arr[i] = -1;
sum += arr[i];
if (sum == 0)
count += 1;
if (mp.has(sum) == true )
count += mp.get(sum);
if (mp.has(sum) == false )
mp.set(sum, 1);
else
mp.set(sum, mp.get(sum)+1);
}
return count;
}
var arr = [1, 0, 0, 1, 0, 1, 1];
var n = arr.length;
document.write( "Count = "
+ countSubarrWithEqualZeroAndOne(arr, n));
</script>
|
PHP
<?php
function countSubarrWithEqualZeroAndOne( $arr , $n ) {
$mp = array ();
$sum = 0;
$count = 0;
for ( $i = 0; $i < $n ; $i ++) {
if ( $arr [ $i ] == 0) {
$arr [ $i ] = -1;
}
$sum += $arr [ $i ];
if ( $sum == 0) {
$count ++;
}
if (isset( $mp [ $sum ])) {
$count += $mp [ $sum ];
}
if (!isset( $mp [ $sum ])) {
$mp [ $sum ] = 1;
} else {
$mp [ $sum ]++;
}
}
return $count ;
}
$arr = array (1, 0, 0, 1, 0, 1, 1);
$n = count ( $arr );
echo "Count = " . countSubarrWithEqualZeroAndOne( $arr , $n );
?>
|
Time Complexity: O(N), where N is the length of the given array
Auxiliary Space: O(N).
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...