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])
// A simple C++ program to find the largest // subarray with equal number of 0s and 1s #include <bits/stdc++.h> using namespace std;
// This function Prints the starting and ending // indexes of the largest subarray with equal // number of 0s and 1s. Also returns the size // of such subarray. int findSubArray( int arr[], int n)
{ int sum = 0;
int maxsize = -1, startindex;
// Pick a starting point as i
for ( int i = 0; i < n - 1; i++) {
sum = (arr[i] == 0) ? -1 : 1;
// Consider all subarrays starting from i
for ( int j = i + 1; j < n; j++) {
(arr[j] == 0) ? (sum += -1) : (sum += 1);
// If this is a 0 sum subarray, then
// compare it with maximum size subarray
// calculated so far
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;
} /* Driver code*/ int main()
{ int arr[] = { 1, 0, 0, 1, 0, 1, 1 };
int size = sizeof (arr) / sizeof (arr[0]);
findSubArray(arr, size);
return 0;
} // This code is contributed by rathbhupendra |
// A simple program to find the largest subarray // with equal number of 0s and 1s #include <stdio.h> // This function Prints the starting and ending // indexes of the largest subarray with equal // number of 0s and 1s. Also returns the size // of such subarray. int findSubArray( int arr[], int n)
{ int sum = 0;
int maxsize = -1, startindex;
// Pick a starting point as i
for ( int i = 0; i < n - 1; i++) {
sum = (arr[i] == 0) ? -1 : 1;
// Consider all subarrays starting from i
for ( int j = i + 1; j < n; j++) {
(arr[j] == 0) ? (sum += -1) : (sum += 1);
// If this is a 0 sum subarray, then
// compare it with maximum size subarray
// calculated so far
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;
} /* Driver program to test above functions*/ int main()
{ int arr[] = { 1, 0, 0, 1, 0, 1, 1 };
int size = sizeof (arr) / sizeof (arr[0]);
findSubArray(arr, size);
return 0;
} |
class LargestSubArray {
// This function Prints the starting and ending
// indexes of the largest subarray with equal
// number of 0s and 1s. Also returns the size
// of such subarray.
int findSubArray( int arr[], int n)
{
int sum = 0 ;
int maxsize = - 1 , startindex = 0 ;
int endindex = 0 ;
// Pick a starting point as i
for ( int i = 0 ; i < n - 1 ; i++) {
sum = (arr[i] == 0 ) ? - 1 : 1 ;
// Consider all subarrays starting from i
for ( int j = i + 1 ; j < n; j++) {
if (arr[j] == 0 )
sum += - 1 ;
else
sum += 1 ;
// If this is a 0 sum subarray, then
// compare it with maximum size subarray
// calculated so far
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;
}
/* Driver program to test the above functions */
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);
}
} |
# A simple program to find the largest subarray # with equal number of 0s and 1s # This function Prints the starting and ending # indexes of the largest subarray with equal # number of 0s and 1s. Also returns the size # of such subarray. def findSubArray(arr, n):
sum = 0
maxsize = - 1
# Pick a starting point as i
for i in range ( 0 , n - 1 ):
sum = - 1 if (arr[i] = = 0 ) else 1
# Consider all subarrays starting from i
for j in range (i + 1 , n):
sum = sum + ( - 1 ) if (arr[j] = = 0 ) else sum + 1
# If this is a 0 sum subarray, then
# compare it with maximum size subarray
# calculated so far
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
# Driver program to test above functions arr = [ 1 , 0 , 0 , 1 , 0 , 1 , 1 ]
size = len (arr)
findSubArray(arr, size) # This code is contributed by Smitha Dinesh Semwal |
// A simple program to find the largest subarray // with equal number of 0s and 1s using System;
class GFG {
// This function Prints the starting and ending
// indexes of the largest subarray with equal
// number of 0s and 1s. Also returns the size
// of such subarray.
static int findSubArray( int [] arr, int n)
{
int sum = 0;
int maxsize = -1, startindex = 0;
int endindex = 0;
// Pick a starting point as i
for ( int i = 0; i < n - 1; i++) {
sum = (arr[i] == 0) ? -1 : 1;
// Consider all subarrays starting from i
for ( int j = i + 1; j < n; j++) {
if (arr[j] == 0)
sum += -1;
else
sum += 1;
// If this is a 0 sum subarray, then
// compare it with maximum size subarray
// calculated so far
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;
}
// Driver program
public static void Main()
{
int [] arr = { 1, 0, 0, 1, 0, 1, 1 };
int size = arr.Length;
findSubArray(arr, size);
}
} // This code is contributed by Sam007 |
<?php // A simple program to find the // largest subarray with equal // number of 0s and 1s // This function Prints the starting // and ending indexes of the largest // subarray with equal number of 0s // and 1s. Also returns the size of // such subarray. function findSubArray(& $arr , $n )
{ $sum = 0;
$maxsize = -1;
// Pick a starting point as i
for ( $i = 0; $i < $n - 1; $i ++)
{
$sum = ( $arr [ $i ] == 0) ? -1 : 1;
// Consider all subarrays
// starting from i
for ( $j = $i + 1; $j < $n ; $j ++)
{
( $arr [ $j ] == 0) ?
( $sum += -1) : ( $sum += 1);
// If this is a 0 sum subarray,
// then compare it with maximum
// size subarray calculated so far
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 ;
} // Driver Code $arr = array (1, 0, 0, 1, 0, 1, 1);
$size = sizeof( $arr );
findSubArray( $arr , $size );
// This code is contributed // by ChitraNayal ?> |
class LargestSubArray { // This function Prints the starting and ending
// indexes of the largest subarray with equal
// number of 0s and 1s. Also returns the size
// of such subarray.
findSubArray(arr, n) {
let sum = 0;
let maxsize = -1;
let startindex = 0;
let endindex = 0;
// Pick a starting point as i
for (let i = 0; i < n - 1; i++) {
sum = (arr[i] == 0) ? -1 : 1;
// Consider all subarrays starting from i
for (let j = i + 1; j < n; j++) {
if (arr[j] == 0)
sum += -1;
else
sum += 1;
// If this is a 0 sum subarray, then
// compare it with maximum size subarray
// calculated so far
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;
}
/* Driver program to test the above functions */
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(); //This code is Contributed by chinmaya121221 |
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++ program to find largest subarray with equal number of // 0's and 1's. #include <bits/stdc++.h> using namespace std;
// Returns largest subarray with equal number of 0s and 1s int maxLen( int arr[], int n)
{ // Creates an empty hashMap hM
unordered_map< int , int > hM;
int sum = 0; // Initialize sum of elements
int max_len = 0; // Initialize result
int ending_index = -1;
for ( int i = 0; i < n; i++)
arr[i] = (arr[i] == 0) ? -1 : 1;
// Traverse through the given array
for ( int i = 0; i < n; i++) {
// Add current element to sum
sum += arr[i];
// To handle sum=0 at last index
if (sum == 0) {
max_len = i + 1;
ending_index = i;
}
// If this sum is seen before, then update max_len
// if required
if (hM.find(sum) != hM.end()) {
if (max_len < i - hM[sum]) {
max_len = i - hM[sum];
ending_index = i;
}
}
else // Else put this sum in hash table
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;
} // Driver method int main()
{ int arr[] = { 1, 0, 0, 1, 0, 1, 1 };
int n = sizeof (arr) / sizeof (arr[0]);
maxLen(arr, n);
return 0;
} // This code is contributed by Aditya Goel |
// A O(n) program to find the largest subarray // with equal number of 0s and 1s #include <stdio.h> #include <stdlib.h> // A utility function to get maximum of two // integers int max( int a, int b) { return a > b ? a : b; }
// This function Prints the starting and ending // indexes of the largest subarray with equal // number of 0s and 1s. Also returns the size // of such subarray. int findSubArray( int arr[], int n)
{ // variables to store result values
int maxsize = -1, startindex;
// Create an auxiliary array sunmleft[].
// sumleft[i] will be sum of array
// elements from arr[0] to arr[i]
int sumleft[n];
// For min and max values in sumleft[]
int min, max;
int i;
// Fill sumleft array and get min and max
// values in it. Consider 0 values in arr[]
// as -1
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];
}
// Now calculate the max value of j - i such
// that sumleft[i] = sumleft[j]. The idea is
// to create a hash table to store indexes of all
// visited values.
// If you see a value again, that it is a case of
// sumleft[i] = sumleft[j]. Check if this j-i is
// more than maxsize.
// The optimum size of hash will be max-min+1 as
// these many different values of sumleft[i] are
// possible. Since we use optimum size, we need
// to shift all values in sumleft[] by min before
// using them as an index in hash[].
int hash[max - min + 1];
// Initialize hash table
for (i = 0; i < max - min + 1; i++)
hash[i] = -1;
for (i = 0; i < n; i++) {
// Case 1: when the subarray starts from
// index 0
if (sumleft[i] == 0) {
maxsize = i + 1;
startindex = 0;
}
// Case 2: fill hash table value. If already
// filled, 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;
}
}
}
if (maxsize == -1)
printf ( "No such subarray" );
else
printf ( "%d to %d" , startindex,
startindex + maxsize - 1);
return maxsize;
} /* Driver program to test above functions */ int main()
{ int arr[] = { 1, 0, 0, 1, 0, 1, 1 };
int size = sizeof (arr) / sizeof (arr[0]);
findSubArray(arr, size);
return 0;
} |
import java.util.HashMap;
class LargestSubArray1 {
// Returns largest subarray with
// equal number of 0s and 1s
int maxLen( int arr[], int n)
{
// Creates an empty hashMap hM
HashMap<Integer, Integer> hM
= new HashMap<Integer, Integer>();
// Initialize sum of elements
int sum = 0 ;
// Initialize result
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 ;
}
// Traverse through the given array
for ( int i = 0 ; i < n; i++) {
// Add current element to sum
sum += arr[i];
// To handle sum=0 at last index
if (sum == 0 ) {
max_len = i + 1 ;
ending_index = i;
}
// If this sum is seen before,
// then update max_len if required
if (hM.containsKey(sum)) {
if (max_len < i - hM.get(sum)) {
max_len = i - hM.get(sum);
ending_index = i;
}
}
else // Else put this sum in hash table
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;
}
/* Driver program to test the above functions */
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);
}
} // This code has been by Mayank Jaiswal(mayank_24) |
# Python 3 program to find largest # subarray with equal number of # 0's and 1's. # Returns largest subarray with # equal number of 0s and 1s def maxLen(arr, n):
# NOTE: Dictionary in python in
# implemented as Hash Maps.
# Create an empty hash map (dictionary)
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
# Traverse through the given array
for i in range ( 0 , n):
# Add current element to sum
curr_sum = curr_sum + arr[i]
# To handle sum = 0 at last index
if (curr_sum = = 0 ):
max_len = i + 1
ending_index = i
# If this sum is seen before,
if curr_sum in hash_map:
# If max_len is smaller than new subarray
# Update max_len and ending_index
if max_len < i - hash_map[curr_sum]:
max_len = i - hash_map[curr_sum]
ending_index = i
else :
# else put this sum in dictionary
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
# Driver Code arr = [ 1 , 0 , 0 , 1 , 0 , 1 , 1 ]
n = len (arr)
maxLen(arr, n) # This code is contributed # by Tarun Garg |
// C# program to find the largest subarray // with equal number of 0s and 1s using System;
using System.Collections.Generic;
class LargestSubArray1 {
// Returns largest subarray with
// equal number of 0s and 1s
public virtual int maxLen( int [] arr, int n)
{
// Creates an empty Dictionary hM
Dictionary< int ,
int >
hM = new Dictionary< int ,
int >();
int sum = 0; // Initialize sum of elements
int max_len = 0; // Initialize result
int ending_index = -1;
int start_index = 0;
for ( int i = 0; i < n; i++) {
arr[i] = (arr[i] == 0) ? -1 : 1;
}
// Traverse through the given array
for ( int i = 0; i < n; i++) {
// Add current element to sum
sum += arr[i];
// To handle sum=0 at last index
if (sum == 0) {
max_len = i + 1;
ending_index = i;
}
// If this sum is seen before,
// then update max_len
// if required
if (hM.ContainsKey(sum)) {
if (max_len < i - hM[sum]) {
max_len = i - hM[sum];
ending_index = i;
}
}
else // Else put this sum in hash table
{
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;
}
// Driver Code
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);
}
} // This code is contributed by Shrikant13 |
// Returns largest subarray with equal number of 0s and 1s function maxLen(arr, n) {
// Creates an empty hashMap hM
const hM = new Map();
// Initialize sum of elements
let sum = 0;
// Initialize result
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;
}
// Traverse through the given array
for (let i = 0; i < n; i++) {
// Add current element to sum
sum += arr[i];
// To handle sum=0 at last index
if (sum == 0) {
max_len = i + 1;
ending_index = i;
}
// If this sum is seen before,
// then update max_len if required
if (hM.has(sum)) {
if (max_len < i - hM.get(sum)) {
max_len = i - hM.get(sum);
ending_index = i;
}
} else // Else put this sum in hash table
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;
} // Driver program to test the above functions let arr = [1, 0, 0, 1, 0, 1, 1]; let n = arr.length; maxLen(arr, n); //This code is Contributed by chinmaya121221 |
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.