Given a binary array containing 0 and 1, find maximum length sub-array having equal number of 0’s and 1’s.





For example,



Input: { 0, 0, 1, 0, 1, 0, 0 }



Output: Largest subarray is { 0, 1, 0, 1 } or { 1, 0, 1, 0}



Naive solution would be to consider all sub-arrays and for each sub-array, we count total number of 0’s and 1’s present. If sub-array contains equal number of 0’s and 1’s , we update maximum length sub-array if required. The time complexity of naive solution is O(n3) as there are n2 sub-arrays and it takes O(n) time to find count 0’s and 1’s . The method can be optimized to run in O(n2) time by calculating count of 0’s and 1’s in constant time.

We can use map to solve this problem in linear time. The idea is to replace 0 with -1 and find out the largest subarray with 0 sum. To find largest subarray with 0 sum, we create an empty map which stores the ending index of first sub-array having given sum. We traverse the given array, and maintain sum of elements seen so far.

If sum is seen for first time, insert the sum with its index into the map.



If sum is seen before, there exists a sub-array with 0 sum which ends at current index and we update maximum length sub-array if current sub-array has more length.

C++ #include <iostream> #include <unordered_map> using namespace std; // Function to find maximum length sub-array having equal number // of 0's and 1's void max_len_subarray(int arr[], int n) { // create an empty map to store ending index of first sub-array // having some sum unordered_map<int, int> map; // insert (0, -1) pair into the set to handle the case when // sub-array with sum 0 starts from index 0 map[0] = -1; // len stores the maximum length of sub-array with sum 0 int len = 0; // stores ending index of maximum length sub-array having sum 0 int ending_index = -1; int sum = 0; // Traverse through the given array for (int i = 0; i < n; i++) { // sum of elements so far (replace 0 with -1) sum += (arr[i] == 0)? -1 : 1; // if sum is seen before if (map.find(sum) != map.end()) { // update length and ending index of maximum length // sub-array having sum 0 if (len < i - map[sum]) { len = i - map[sum]; ending_index = i; } } // if sum is seen for first time, insert sum with its // index into the map else { map[sum] = i; } } // print the sub-array if present if (ending_index != -1) { cout << "[" << ending_index - len + 1 << ", " << ending_index << "]"; } else { cout << "No sub-array exists"; } } int main() { int arr[] = { 0, 0, 1, 0, 1, 0, 0 }; int n = sizeof(arr) / sizeof(arr[0]); max_len_subarray(arr, n); return 0; } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 #include <iostream> #include <unordered_map> using namespace std ; // Function to find maximum length sub-array having equal number // of 0's and 1's void max_len_subarray ( int arr [ ] , int n ) { // create an empty map to store ending index of first sub-array // having some sum unordered_map < int , int > map ; // insert (0, -1) pair into the set to handle the case when // sub-array with sum 0 starts from index 0 map [ 0 ] = - 1 ; // len stores the maximum length of sub-array with sum 0 int len = 0 ; // stores ending index of maximum length sub-array having sum 0 int ending_index = - 1 ; int sum = 0 ; // Traverse through the given array for ( int i = 0 ; i < n ; i ++ ) { // sum of elements so far (replace 0 with -1) sum += ( arr [ i ] == 0 ) ? - 1 : 1 ; // if sum is seen before if ( map . find ( sum ) != map . end ( ) ) { // update length and ending index of maximum length // sub-array having sum 0 if ( len < i - map [ sum ] ) { len = i - map [ sum ] ; ending_index = i ; } } // if sum is seen for first time, insert sum with its // index into the map else { map [ sum ] = i ; } } // print the sub-array if present if ( ending_index != - 1 ) { cout << "[" << ending_index - len + 1 << ", " << ending_index << "]" ; } else { cout << "No sub-array exists" ; } } int main ( ) { int arr [ ] = { 0 , 0 , 1 , 0 , 1 , 0 , 0 } ; int n = sizeof ( arr ) / sizeof ( arr [ 0 ] ) ; max_len_subarray ( arr , n ) ; return 0 ; } Download Run Code Output:



[1, 4]

Java import java.util.Map; import java.util.HashMap; class Main { // Function to find maximum length sub-array having equal number // of 0's and 1's public static void maxLenSubarray(int[] A) { // create an empty Hash Map to store ending index of first // sub-array having some sum Map<Integer, Integer> map = new HashMap<>(); // insert (0, -1) pair into the set to handle the case when // sub-array with sum 0 starts from index 0 map.put(0, -1); // len stores the maximum length of sub-array with sum 0 int len = 0; // stores ending index of maximum length sub-array having sum 0 int ending_index = -1; int sum = 0; // Traverse through the given array for (int i = 0; i < A.length; i++) { // sum of elements so far (replace 0 with -1) sum += (A[i] == 0)? -1: 1; // if sum is seen before if (map.containsKey(sum)) { // update length and ending index of maximum length // sub-array having sum 0 if (len < i - map.get(sum)) { len = i - map.get(sum); ending_index = i; } } // if sum is seen for first time, insert sum with its // index into the map else { map.put(sum, i); } } // print the sub-array if present if (ending_index != -1) { System.out.println("[" + (ending_index - len + 1) + ", " + ending_index + "]"); } else { System.out.println("No sub-array exists"); } } public static void main (String[] args) { int[] A = { 0, 0, 1, 0, 1, 0, 0 }; maxLenSubarray(A); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 import java . util . Map ; import java . util . HashMap ; class Main { // Function to find maximum length sub-array having equal number // of 0's and 1's public static void maxLenSubarray ( int [ ] A ) { // create an empty Hash Map to store ending index of first // sub-array having some sum Map < Integer , Integer > map = new HashMap <> ( ) ; // insert (0, -1) pair into the set to handle the case when // sub-array with sum 0 starts from index 0 map . put ( 0 , - 1 ) ; // len stores the maximum length of sub-array with sum 0 int len = 0 ; // stores ending index of maximum length sub-array having sum 0 int ending_index = - 1 ; int sum = 0 ; // Traverse through the given array for ( int i = 0 ; i < A . length ; i ++ ) { // sum of elements so far (replace 0 with -1) sum += ( A [ i ] == 0 ) ? - 1 : 1 ; // if sum is seen before if ( map . containsKey ( sum ) ) { // update length and ending index of maximum length // sub-array having sum 0 if ( len < i - map . get ( sum ) ) { len = i - map . get ( sum ) ; ending_index = i ; } } // if sum is seen for first time, insert sum with its // index into the map else { map . put ( sum , i ) ; } } // print the sub-array if present if ( ending_index != - 1 ) { System . out . println ( "[" + ( ending_index - len + 1 ) + ", " + ending_index + "]" ) ; } else { System . out . println ( "No sub-array exists" ) ; } } public static void main ( String [ ] args ) { int [ ] A = { 0 , 0 , 1 , 0 , 1 , 0 , 0 } ; maxLenSubarray ( A ) ; } } Download Run Code Output:



[1, 4]

Python # Function to find maximum length sublist having equal number of 0's and 1's def maxLenSublist(A): # create an empty Hash Map to store ending index of first # sublist having some sum dict = {} # insert (0, -1) pair into the set to handle the case when # sublist with sum 0 starts from index 0 dict[0] = -1 # length stores the maximum length of sublist with sum 0 length = 0 # stores ending index of maximum length sublist having sum 0 ending_index = -1 sum = 0 # Traverse through the given list for i in range(len(A)): # sum of elements so far (replace 0 with -1) sum += -1 if (A[i] == 0) else 1 # if sum is seen before if sum in dict: # update length and ending index of maximum length # sublist having sum 0 if length < i - dict.get(sum): length = i - dict.get(sum) ending_index = i # if sum is seen for first time, insert sum with its # index into the dict else: dict[sum] = i # print the sublist if present if ending_index != -1: print((ending_index - length + 1, ending_index)) else: print("No sublist exists") if __name__ == '__main__': A = [0, 0, 1, 0, 1, 0, 0] maxLenSublist(A) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 # Function to find maximum length sublist having equal number of 0's and 1's def maxLenSublist ( A ) : # create an empty Hash Map to store ending index of first # sublist having some sum dict = { } # insert (0, -1) pair into the set to handle the case when # sublist with sum 0 starts from index 0 dict [ 0 ] = - 1 # length stores the maximum length of sublist with sum 0 length = 0 # stores ending index of maximum length sublist having sum 0 ending_index = - 1 sum = 0 # Traverse through the given list for i in range ( len ( A ) ) : # sum of elements so far (replace 0 with -1) sum += - 1 if ( A [ i ] == 0 ) else 1 # if sum is seen before if sum in dict : # update length and ending index of maximum length # sublist having sum 0 if length < i - dict . get ( sum ) : length = i - dict . get ( sum ) ending_index = i # if sum is seen for first time, insert sum with its # index into the dict else : dict [ sum ] = i # print the sublist if present if ending_index != - 1 : print ( ( ending_index - length + 1 , ending_index ) ) else : print ( "No sublist exists" ) if __name__ == '__main__' : A = [ 0 , 0 , 1 , 0 , 1 , 0 , 0 ] maxLenSublist ( A ) Download Run Code Output:



(1, 4)







The time complexity of above solution is O(n) and auxiliary space used by the program is O(n).









(28 votes, average: 4.71 out of 5)

Loading...

Thanks for reading.