Largest subarray with equal number of 0s and 1s
Last Updated :
06 Mar, 2023
Given an array containing only 0s and 1s, find the largest subarray which contains equal no of 0s and 1s. The expected time complexity is O(n).
Examples:
Input: arr[] = {1, 0, 1, 1, 1, 0, 0}
Output: 1 to 6
(Starting and Ending indexes of output subarray)
Input: arr[] = {1, 1, 1, 1}
Output: No such subarray
Input: arr[] = {0, 0, 1, 1, 0}
Output: 0 to 3 Or 1 to 4
Method 1: Brute Force.
Approach: The brute force approach in these type of questions is to generate all the possible sub-arrays. Then firstly check whether the sub-array has equal number of 0’s and 1’s or not. To make this process easy take cumulative sum of the sub-arrays taking 0’s as -1 and 1’s as it is. The point where cumulative sum = 0 will signify that the sub-array from starting till that point has equal number of 0’s and 1’s. Now as this is a valid sub-array, compare it’s size with the maximum size of such sub-array found till now.
Algorithm :
- Use a starting a pointer which signifies the starting point of the sub-array.
- Take a variable sum=0 which will take the cumulative sum of all the sub-array elements.
- Initialize it with value 1 if the value at starting point=1 else initialize it with -1.
- Now start an inner loop and start taking the cumulative sum of elements following the same logic.
- If the cumulative sum (value of sum)=0 it signifies that the sub-array has equal number of 0’s and 1’s.
- Now compare its size with the size of the largest sub-array if it is greater store the first index of such sub-array in a variable and update the value of size.
- Print the sub-array with the starting index and size returned by the above algorithm.
Pseudo Code:
Run a loop from i=0 to n-2
if(arr[i]==1)
sum=1
else
sum=-1
Run inner loop from j=i+1 to n-1
sum+=arr[j]
if(sum==0)
if(j-i+1>max_size)
start_index=i
max_size=j-i+1
Run a loop from i=start_index till max_size-1
print(arr[i])
C++
#include <bits/stdc++.h>
using namespace std;
int findSubArray( int arr[], int n)
{
int sum = 0;
int maxsize = -1, startindex;
for ( int i = 0; i < n - 1; i++) {
sum = (arr[i] == 0) ? -1 : 1;
for ( int j = i + 1; j < n; j++) {
(arr[j] == 0) ? (sum += -1) : (sum += 1);
if (sum == 0 && maxsize < j - i + 1) {
maxsize = j - i + 1;
startindex = i;
}
}
}
if (maxsize == -1)
cout << "No such subarray" ;
else
cout << startindex << " to "
<< startindex + maxsize - 1;
return maxsize;
}
int main()
{
int arr[] = { 1, 0, 0, 1, 0, 1, 1 };
int size = sizeof (arr) / sizeof (arr[0]);
findSubArray(arr, size);
return 0;
}
|
C
#include <stdio.h>
int findSubArray( int arr[], int n)
{
int sum = 0;
int maxsize = -1, startindex;
for ( int i = 0; i < n - 1; i++) {
sum = (arr[i] == 0) ? -1 : 1;
for ( int j = i + 1; j < n; j++) {
(arr[j] == 0) ? (sum += -1) : (sum += 1);
if (sum == 0 && maxsize < j - i + 1) {
maxsize = j - i + 1;
startindex = i;
}
}
}
if (maxsize == -1)
printf ( "No such subarray" );
else
printf ( "%d to %d" , startindex, startindex + maxsize - 1);
return maxsize;
}
int main()
{
int arr[] = { 1, 0, 0, 1, 0, 1, 1 };
int size = sizeof (arr) / sizeof (arr[0]);
findSubArray(arr, size);
return 0;
}
|
Java
class LargestSubArray {
int findSubArray( int arr[], int n)
{
int sum = 0 ;
int maxsize = - 1 , startindex = 0 ;
int endindex = 0 ;
for ( int i = 0 ; i < n - 1 ; i++) {
sum = (arr[i] == 0 ) ? - 1 : 1 ;
for ( int j = i + 1 ; j < n; j++) {
if (arr[j] == 0 )
sum += - 1 ;
else
sum += 1 ;
if (sum == 0 && maxsize < j - i + 1 ) {
maxsize = j - i + 1 ;
startindex = i;
}
}
}
endindex = startindex + maxsize - 1 ;
if (maxsize == - 1 )
System.out.println( "No such subarray" );
else
System.out.println(startindex + " to " + endindex);
return maxsize;
}
public static void main(String[] args)
{
LargestSubArray sub;
sub = new LargestSubArray();
int arr[] = { 1 , 0 , 0 , 1 , 0 , 1 , 1 };
int size = arr.length;
sub.findSubArray(arr, size);
}
}
|
Python3
def findSubArray(arr, n):
sum = 0
maxsize = - 1
for i in range ( 0 , n - 1 ):
sum = - 1 if (arr[i] = = 0 ) else 1
for j in range (i + 1 , n):
sum = sum + ( - 1 ) if (arr[j] = = 0 ) else sum + 1
if ( sum = = 0 and maxsize < j - i + 1 ):
maxsize = j - i + 1
startindex = i
if (maxsize = = - 1 ):
print ( "No such subarray" );
else :
print (startindex, "to" , startindex + maxsize - 1 );
return maxsize
arr = [ 1 , 0 , 0 , 1 , 0 , 1 , 1 ]
size = len (arr)
findSubArray(arr, size)
|
C#
using System;
class GFG {
static int findSubArray( int [] arr, int n)
{
int sum = 0;
int maxsize = -1, startindex = 0;
int endindex = 0;
for ( int i = 0; i < n - 1; i++) {
sum = (arr[i] == 0) ? -1 : 1;
for ( int j = i + 1; j < n; j++) {
if (arr[j] == 0)
sum += -1;
else
sum += 1;
if (sum == 0 && maxsize < j - i + 1) {
maxsize = j - i + 1;
startindex = i;
}
}
}
endindex = startindex + maxsize - 1;
if (maxsize == -1)
Console.WriteLine( "No such subarray" );
else
Console.WriteLine(startindex + " to " + endindex);
return maxsize;
}
public static void Main()
{
int [] arr = { 1, 0, 0, 1, 0, 1, 1 };
int size = arr.Length;
findSubArray(arr, size);
}
}
|
PHP
<?php
function findSubArray(& $arr , $n )
{
$sum = 0;
$maxsize = -1;
for ( $i = 0; $i < $n - 1; $i ++)
{
$sum = ( $arr [ $i ] == 0) ? -1 : 1;
for ( $j = $i + 1; $j < $n ; $j ++)
{
( $arr [ $j ] == 0) ?
( $sum += -1) : ( $sum += 1);
if ( $sum == 0 && $maxsize < $j - $i + 1)
{
$maxsize = $j - $i + 1;
$startindex = $i ;
}
}
}
if ( $maxsize == -1)
echo "No such subarray" ;
else
echo $startindex . " to " .
( $startindex + $maxsize - 1);
return $maxsize ;
}
$arr = array (1, 0, 0, 1, 0, 1, 1);
$size = sizeof( $arr );
findSubArray( $arr , $size );
?>
|
Javascript
class LargestSubArray {
findSubArray(arr, n) {
let sum = 0;
let maxsize = -1;
let startindex = 0;
let endindex = 0;
for (let i = 0; i < n - 1; i++) {
sum = (arr[i] == 0) ? -1 : 1;
for (let j = i + 1; j < n; j++) {
if (arr[j] == 0)
sum += -1;
else
sum += 1;
if (sum == 0 && maxsize < j - i + 1) {
maxsize = j - i + 1;
startindex = i;
}
}
}
endindex = startindex + maxsize - 1;
if (maxsize == -1)
console.log( "No such subarray" );
else
console.log(startindex + " to " + endindex);
return maxsize;
}
main() {
const sub = new LargestSubArray();
const arr = [1, 0, 0, 1, 0, 1, 1];
const size = arr.length;
sub.findSubArray(arr, size);
}
}
const sub = new LargestSubArray();
sub.main();
|
Output:
0 to 5
Complexity Analysis:
- Time Complexity: O(n^2).
As all the possible sub-arrays are generated using a pair of nested loops.
- Auxiliary Space: O(1).
As no extra data structure is used which takes auxiliary space.
Method 2: Hashmap.
Approach: The concept of taking cumulative sum, taking 0’s as -1 will help us in optimizing the approach. While taking the cumulative sum, there are two cases when there can be a sub-array with equal number of 0’s and 1’s.
- When cumulative sum=0, which signifies that sub-array from index (0) till present index has equal number of 0’s and 1’s.
- When we encounter a cumulative sum value which we have already encountered before, which means that sub-array from the previous index+1 till the present index has equal number of 0’s and 1’s as they give a cumulative sum of 0 .
In a nutshell this problem is equivalent to finding two indexes i & j in array[] such that array[i] = array[j] and (j-i) is maximum. To store the first occurrence of each unique cumulative sum value we use a hash_map wherein if we get that value again we can find the sub-array size and compare it with the maximum size found till now.
Algorithm :
- Let input array be arr[] of size n and max_size be the size of output sub-array.
- Create a temporary array sumleft[] of size n. Store the sum of all elements from arr[0] to arr[i] in sumleft[i].
- There are two cases, the output sub-array may start from 0th index or may start from some other index. We will return the max of the values obtained by two cases.
- To find the maximum length sub-array starting from 0th index, scan the sumleft[] and find the maximum i where sumleft[i] = 0.
- Now, we need to find the subarray where subarray sum is 0 and start index is not 0. This problem is equivalent to finding two indexes i & j in sumleft[] such that sumleft[i] = sumleft[j] and j-i is maximum. To solve this, we create a hash table with size = max-min+1 where min is the minimum value in the sumleft[] and max is the maximum value in the sumleft[]. Hash the leftmost occurrences of all different values in sumleft[]. The size of hash is chosen as max-min+1 because there can be these many different possible values in sumleft[]. Initialize all values in hash as -1.
- To fill and use hash[], traverse sumleft[] from 0 to n-1. If a value is not present in hash[], then store its index in hash. If the value is present, then calculate the difference of current index of sumleft[] and previously stored value in hash[]. If this difference is more than maxsize, then update the maxsize.
- To handle corner cases (all 1s and all 0s), we initialize maxsize as -1. If the maxsize remains -1, then print there is no such subarray.
Pseudo Code:
int sum_left[n]
Run a loop from i=0 to n-1
if(arr[i]==0)
sumleft[i] = sumleft[i-1]+-1
else
sumleft[i] = sumleft[i-1]+ 1
if (sumleft[i] > max)
max = sumleft[i];
Run a loop from i=0 to n-1
if (sumleft[i] == 0)
{
maxsize = i+1;
startindex = 0;
}
// Case 2: fill hash table value. If already
then use it
if (hash[sumleft[i]-min] == -1)
hash[sumleft[i]-min] = i;
else
{
if ((i - hash[sumleft[i]-min]) > maxsize)
{
maxsize = i - hash[sumleft[i]-min];
startindex = hash[sumleft[i]-min] + 1;
}
}
return maxsize
C++
#include <bits/stdc++.h>
using namespace std;
int maxLen( int arr[], int n)
{
unordered_map< int , int > hM;
int sum = 0;
int max_len = 0;
int ending_index = -1;
for ( int i = 0; i < n; i++)
arr[i] = (arr[i] == 0) ? -1 : 1;
for ( int i = 0; i < n; i++) {
sum += arr[i];
if (sum == 0) {
max_len = i + 1;
ending_index = i;
}
if (hM.find(sum) != hM.end()) {
if (max_len < i - hM[sum]) {
max_len = i - hM[sum];
ending_index = i;
}
}
else
hM[sum] = i;
}
for ( int i = 0; i < n; i++)
arr[i] = (arr[i] == -1) ? 0 : 1;
printf ( "%d to %d\n" ,
ending_index - max_len + 1, ending_index);
return max_len;
}
int main()
{
int arr[] = { 1, 0, 0, 1, 0, 1, 1 };
int n = sizeof (arr) / sizeof (arr[0]);
maxLen(arr, n);
return 0;
}
|
C
#include <stdio.h>
#include <stdlib.h>
int max( int a, int b) { return a > b ? a : b; }
int findSubArray( int arr[], int n)
{
int maxsize = -1, startindex;
int sumleft[n];
int min, max;
int i;
sumleft[0] = ((arr[0] == 0) ? -1 : 1);
min = arr[0];
max = arr[0];
for (i = 1; i < n; i++) {
sumleft[i] = sumleft[i - 1]
+ ((arr[i] == 0) ? -1 : 1);
if (sumleft[i] < min)
min = sumleft[i];
if (sumleft[i] > max)
max = sumleft[i];
}
int hash[max - min + 1];
for (i = 0; i < max - min + 1; i++)
hash[i] = -1;
for (i = 0; i < n; i++) {
if (sumleft[i] == 0) {
maxsize = i + 1;
startindex = 0;
}
if (hash[sumleft[i] - min] == -1)
hash[sumleft[i] - min] = i;
else {
if ((i - hash[sumleft[i] - min]) > maxsize) {
maxsize = i - hash[sumleft[i] - min];
startindex = hash[sumleft[i] - min] + 1;
}
}
}
if (maxsize == -1)
printf ( "No such subarray" );
else
printf ( "%d to %d" , startindex,
startindex + maxsize - 1);
return maxsize;
}
int main()
{
int arr[] = { 1, 0, 0, 1, 0, 1, 1 };
int size = sizeof (arr) / sizeof (arr[0]);
findSubArray(arr, size);
return 0;
}
|
Java
import java.util.HashMap;
class LargestSubArray1 {
int maxLen( int arr[], int n)
{
HashMap<Integer, Integer> hM
= new HashMap<Integer, Integer>();
int sum = 0 ;
int max_len = 0 ;
int ending_index = - 1 ;
int start_index = 0 ;
for ( int i = 0 ; i < n; i++) {
arr[i] = (arr[i] == 0 ) ? - 1 : 1 ;
}
for ( int i = 0 ; i < n; i++) {
sum += arr[i];
if (sum == 0 ) {
max_len = i + 1 ;
ending_index = i;
}
if (hM.containsKey(sum)) {
if (max_len < i - hM.get(sum)) {
max_len = i - hM.get(sum);
ending_index = i;
}
}
else
hM.put(sum, i);
}
for ( int i = 0 ; i < n; i++) {
arr[i] = (arr[i] == - 1 ) ? 0 : 1 ;
}
int end = ending_index - max_len + 1 ;
System.out.println(end + " to " + ending_index);
return max_len;
}
public static void main(String[] args)
{
LargestSubArray1 sub = new LargestSubArray1();
int arr[] = { 1 , 0 , 0 , 1 , 0 , 1 , 1 };
int n = arr.length;
sub.maxLen(arr, n);
}
}
|
Python3
def maxLen(arr, n):
hash_map = {}
curr_sum = 0
max_len = 0
ending_index = - 1
for i in range ( 0 , n):
if (arr[i] = = 0 ):
arr[i] = - 1
else :
arr[i] = 1
for i in range ( 0 , n):
curr_sum = curr_sum + arr[i]
if (curr_sum = = 0 ):
max_len = i + 1
ending_index = i
if curr_sum in hash_map:
if max_len < i - hash_map[curr_sum]:
max_len = i - hash_map[curr_sum]
ending_index = i
else :
hash_map[curr_sum] = i
for i in range ( 0 , n):
if (arr[i] = = - 1 ):
arr[i] = 0
else :
arr[i] = 1
print (ending_index - max_len + 1 , end = " " )
print ( "to" , end = " " )
print (ending_index)
return max_len
arr = [ 1 , 0 , 0 , 1 , 0 , 1 , 1 ]
n = len (arr)
maxLen(arr, n)
|
C#
using System;
using System.Collections.Generic;
class LargestSubArray1 {
public virtual int maxLen( int [] arr, int n)
{
Dictionary< int ,
int >
hM = new Dictionary< int ,
int >();
int sum = 0;
int max_len = 0;
int ending_index = -1;
int start_index = 0;
for ( int i = 0; i < n; i++) {
arr[i] = (arr[i] == 0) ? -1 : 1;
}
for ( int i = 0; i < n; i++) {
sum += arr[i];
if (sum == 0) {
max_len = i + 1;
ending_index = i;
}
if (hM.ContainsKey(sum)) {
if (max_len < i - hM[sum]) {
max_len = i - hM[sum];
ending_index = i;
}
}
else
{
hM[sum] = i;
}
}
for ( int i = 0; i < n; i++) {
arr[i] = (arr[i] == -1) ? 0 : 1;
}
int end = ending_index - max_len + 1;
Console.WriteLine(end + " to " + ending_index);
return max_len;
}
public static void Main( string [] args)
{
LargestSubArray1 sub = new LargestSubArray1();
int [] arr = new int [] {
1,
0,
0,
1,
0,
1,
1
};
int n = arr.Length;
sub.maxLen(arr, n);
}
}
|
Javascript
function maxLen(arr, n) {
const hM = new Map();
let sum = 0;
let max_len = 0;
let ending_index = -1;
let start_index = 0;
for (let i = 0; i < n; i++) {
arr[i] = (arr[i] == 0) ? -1 : 1;
}
for (let i = 0; i < n; i++) {
sum += arr[i];
if (sum == 0) {
max_len = i + 1;
ending_index = i;
}
if (hM.has(sum)) {
if (max_len < i - hM.get(sum)) {
max_len = i - hM.get(sum);
ending_index = i;
}
} else
hM.set(sum, i);
}
for (let i = 0; i < n; i++) {
arr[i] = (arr[i] == -1) ? 0 : 1;
}
let end = ending_index - max_len + 1;
console.log(`${end} to ${ending_index}`);
return max_len;
}
let arr = [1, 0, 0, 1, 0, 1, 1];
let n = arr.length;
maxLen(arr, n);
|
Output:
0 to 5
Complexity Analysis:
- Time Complexity: O(n).
As the given array is traversed only once.
- Auxiliary Space: O(n).
As hash_map has been used which takes extra space.
Please Login to comment...