Maximum difference of zeros and ones in binary string
Given a binary string of 0s and 1s. The task is to find the length of the substring which is having a maximum difference between the number of 0s and the number of 1s (number of 0s – number of 1s). In case of all 1s print -1.
Examples:
Input : S = "11000010001"
Output : 6
From index 2 to index 9, there are 7
0s and 1 1s, so number of 0s - number
of 1s is 6.
Input : S = "1111"
Output : -1
Now, at each index i we need to make decision whether to take it or skip it. So, declare a 2D array of size n x 2, where n is the length of the given binary string, say dp[n][2].
dp[i][0] define the maximum value upto
index i, when we skip the i-th
index element.
dp[i][1] define the maximum value upto
index i after taking the i-th
index element.
Therefore, we can derive dp[i][] as:
dp[i][0] = max(dp[i+1][0], dp[i+1][1] + arr[i])
dp[i][1] = max(dp[i+1][1] + arr[i], 0)
For all ones, we check this case explicitly.
C++
// CPP Program to find the length of // substring with maximum difference of // zeroes and ones in binary string. #include <bits/stdc++.h> #define MAX 100 using namespace std; // Return true if there all 1s bool allones(string s, int n) { // Checking each index is 1 or not. int co = 0; for ( int i = 0; i < s.size(); i++) co += (s[i] == '1' ); return (co == n); } // Find the length of substring with maximum // difference of zeroes and ones in binary // string int findlength( int arr[], string s, int n, int ind, int st, int dp[][3]) { // If string is over. if (ind >= n) return 0; // If the state is already calculated. if (dp[ind][st] != -1) return dp[ind][st]; if (st == 0) return dp[ind][st] = max(arr[ind] + findlength(arr, s, n, ind + 1, 1, dp), findlength(arr, s, n, ind + 1, 0, dp)); else return dp[ind][st] = max(arr[ind] + findlength(arr, s, n, ind + 1, 1, dp), 0); } // Returns length of substring which is // having maximum difference of number // of 0s and number of 1s int maxLen(string s, int n) { // If all 1s return -1. if (allones(s, n)) return -1; // Else find the length. int arr[MAX] = { 0 }; for ( int i = 0; i < n; i++) arr[i] = (s[i] == '0' ? 1 : -1); int dp[MAX][3]; memset (dp, -1, sizeof dp); return findlength(arr, s, n, 0, 0, dp); } // Driven Program int main() { string s = "11000010001" ; int n = 11; cout << maxLen(s, n) << endl; return 0; } |
Java
// Java Program to find the length of // substring with maximum difference of // zeroes and ones in binary string. import java.util.Arrays; class GFG { static final int MAX= 100 ; // Return true if there all 1s static boolean allones(String s, int n) { // Checking each index is 0 or not. int co = 0 ; for ( int i = 0 ; i < s.length(); i++) if (s.charAt(i) == '1' ) co += 1 ; return (co == n); } // Find the length of substring with maximum // difference of zeroes and ones in binary // string static int findlength( int arr[], String s, int n, int ind, int st, int dp[][]) { // If string is over. if (ind >= n) return 0 ; // If the state is already calculated. if (dp[ind][st] != - 1 ) return dp[ind][st]; if (st == 0 ) return dp[ind][st] = Math.max(arr[ind] + findlength(arr, s, n, ind + 1 , 1 , dp), findlength(arr, s, n, ind + 1 , 0 , dp)); else return dp[ind][st] = Math.max(arr[ind] + findlength(arr, s, n, ind + 1 , 1 , dp), 0 ); } // Returns length of substring which is // having maximum difference of number // of 0s and number of 1s static int maxLen(String s, int n) { // If all 1s return -1. if (allones(s, n)) return - 1 ; // Else find the length. int arr[] = new int [MAX]; for ( int i = 0 ; i < n; i++) arr[i] = (s.charAt(i) == '0' ? 1 : - 1 ); int dp[][] = new int [MAX][ 3 ]; for ( int [] row : dp) Arrays.fill(row, - 1 ); return findlength(arr, s, n, 0 , 0 , dp); } // Driver code public static void main (String[] args) { String s = "11000010001" ; int n = 11 ; System.out.println(maxLen(s, n)); } } // This code is contributed by Anant Agarwal. |
Python3
# Python Program to find the length of # substring with maximum difference of # zeroes and ones in binary string. MAX = 100 # Return true if there all 1s def allones(s, n): # Checking each index # is 0 or not. co = 0 for i in s: co + = 1 if i = = '1' else 0 return co = = n # Find the length of substring with # maximum difference of zeroes and # ones in binary string def findlength(arr, s, n, ind, st, dp): # If string is over if ind > = n: return 0 # If the state is already calculated. if dp[ind][st] ! = - 1 : return dp[ind][st] if not st: dp[ind][st] = max (arr[ind] + findlength(arr, s, n, ind + 1 , 1 , dp), (findlength(arr, s, n, ind + 1 , 0 , dp))) else : dp[ind][st] = max (arr[ind] + findlength(arr, s, n, ind + 1 , 1 , dp), 0 ) return dp[ind][st] # Returns length of substring which is # having maximum difference of number # of 0s and number of 1s def maxLen(s, n): # If all 1s return -1. if allones(s, n): return - 1 # Else find the length. arr = [ 0 ] * MAX for i in range (n): arr[i] = 1 if s[i] = = '0' else - 1 dp = [[ - 1 ] * 3 for _ in range ( MAX )] return findlength(arr, s, n, 0 , 0 , dp) # Driven Program s = "11000010001" n = 11 print (maxLen(s, n)) # This code is contributed by Ansu Kumari. |
C#
// C# Program to find the length of // substring with maximum difference of // zeroes and ones in binary string. using System; class GFG { static int MAX = 100; // Return true if there all 1s public static bool allones( string s, int n) { // Checking each index is 0 or not. int co = 0; for ( int i = 0; i < s.Length; i++) co += (s[i] == '1' ? 1 : 0); return (co == n); } // Find the length of substring with maximum // difference of zeroes and ones in binary // string public static int findlength( int [] arr, string s, int n, int ind, int st, int [,] dp) { // If string is over. if (ind >= n) return 0; // If the state is already calculated. if (dp[ind,st] != -1) return dp[ind,st]; if (st == 0) return dp[ind,st] = Math.Max(arr[ind] + findlength(arr, s, n, ind + 1, 1, dp), findlength(arr, s, n, ind + 1, 0, dp)); else return dp[ind,st] = Math.Max(arr[ind] + findlength(arr, s, n, ind + 1, 1, dp), 0); } // Returns length of substring which is // having maximum difference of number // of 0s and number of 1s public static int maxLen( string s, int n) { // If all 1s return -1. if (allones(s, n)) return -1; // Else find the length. int [] arr = new int [MAX]; for ( int i = 0; i < n; i++) arr[i] = (s[i] == '0' ? 1 : -1); int [,] dp = new int [MAX,3]; for ( int i = 0; i < MAX; i++) for ( int j = 0; j < 3; j++) dp[i,j] = -1; return findlength(arr, s, n, 0, 0, dp); } // Driven Program static void Main() { string s = "11000010001" ; int n = 11; Console.Write(maxLen(s, n)); } // This code is contributed by DrRoot_ } |
Javascript
<script> // Javascript Program to find the length of // substring with maximum difference of // zeroes and ones in binary string. var MAX = 100; // Return true if there all 1s function allones( s, n) { // Checking each index is 0 or not. var co = 0; for ( var i = 0; i < s.length; i++) co += (s[i] == '1' ); return (co == n); } // Find the length of substring with maximum // difference of zeroes and ones in binary // string function findlength(arr, s, n, ind, st, dp) { // If string is over. if (ind >= n) return 0; // If the state is already calculated. if (dp[ind][st] != -1) return dp[ind][st]; if (st == 0) return dp[ind][st] = Math.max(arr[ind] + findlength(arr, s, n, ind + 1, 1, dp), findlength(arr, s, n, ind + 1, 0, dp)); else return dp[ind][st] = Math.max(arr[ind] + findlength(arr, s, n, ind + 1, 1, dp), 0); } // Returns length of substring which is // having maximum difference of number // of 0s and number of 1s function maxLen( s, n) { // If all 1s return -1. if (allones(s, n)) return -1; // Else find the length. var arr = Array(MAX).fill(0); for ( var i = 0; i < n; i++) arr[i] = (s[i] == '0' ? 1 : -1); var dp = Array.from(Array(MAX), ()=> Array(3).fill(-1)); return findlength(arr, s, n, 0, 0, dp); } // Driven Program var s = "11000010001" ; var n = 11; document.write( maxLen(s, n)); </script> |
6
Time Complexity: O(2*len(s)),
Auxiliary Space: O(len(s))
Efficient approach: Using DP Tabulation method ( Iterative approach )
The approach to solve this problem is same but DP tabulation(bottom-up) method is better then Dp + memoization(top-down) because memoization method needs extra stack space of recursion calls.
Steps to solve this problem :
- Create a DP to store the solution of the subproblems and initialize it with -1.
- Initialize the DP with base cases.
- Now Iterate over subproblems to get the value of current problem form previous computation of subproblems stored in DP
- Return the final solution stored in dp[0][0].
Implementation :
C++
// CPP Program to find the length of // substring with maximum difference of // zeroes and ones in binary string. #include <bits/stdc++.h> #define MAX 100 using namespace std; // Returns length of substring which is // having maximum difference of number // of 0s and number of 1s int maxLen(string s, int n) { bool all_zeros = true , all_ones = true ; for ( int i = 0; i < n; i++) { if (s[i] == '0' ) all_ones = false ; else all_zeros = false ; } if (all_zeros || all_ones) return -1; int arr[MAX] = {0}; for ( int i = 0; i < n; i++) arr[i] = (s[i] == '0' ? 1 : -1); int dp[MAX][3]; memset (dp, -1, sizeof (dp)); // Initializing base case values dp[n][0] = dp[n][1] = dp[n][2] = 0; // Computing DP values from bottom up for ( int i = n - 1; i >= 0; i--) { for ( int st = 0; st <= 2; st++) { if (st == 0) dp[i][st] = max(arr[i] + dp[i + 1][1], dp[i + 1][0]); else if (st == 1) dp[i][st] = max(arr[i] + dp[i + 1][1], 0); else dp[i][st] = max(arr[i] + dp[i + 1][1], dp[i + 1][2]); } } // Returning the maximum length of substring with difference // between 0's and 1's equal to the maximum value of dp return dp[0][0]; } // Driver code int main() { string s = "11000010001" ; int n = s.length(); cout << maxLen(s, n) << endl; return 0; } |
Java
import java.util.Arrays; public class Main { // Returns length of substring which is // having maximum difference of number // of 0s and number of 1s public static int maxLen(String s, int n) { boolean all_zeros = true , all_ones = true ; for ( int i = 0 ; i < n; i++) { if (s.charAt(i) == '0' ) all_ones = false ; else all_zeros = false ; } if (all_zeros || all_ones) return - 1 ; int [] arr = new int [ 100 ]; for ( int i = 0 ; i < n; i++) arr[i] = (s.charAt(i) == '0' ? 1 : - 1 ); int [][] dp = new int [ 100 ][ 3 ]; for ( int [] row : dp) Arrays.fill(row, - 1 ); // Initializing base case values dp[n][ 0 ] = dp[n][ 1 ] = dp[n][ 2 ] = 0 ; // Computing DP values from bottom up for ( int i = n - 1 ; i >= 0 ; i--) { for ( int st = 0 ; st <= 2 ; st++) { if (st == 0 ) dp[i][st] = Math.max(arr[i] + dp[i + 1 ][ 1 ], dp[i + 1 ][ 0 ]); else if (st == 1 ) dp[i][st] = Math.max( arr[i] + dp[i + 1 ][ 1 ], 0 ); else dp[i][st] = Math.max(arr[i] + dp[i + 1 ][ 1 ], dp[i + 1 ][ 2 ]); } } // Returning the maximum length of substring with // difference between 0's and 1's equal to the // maximum value of dp return dp[ 0 ][ 0 ]; } // Driver code public static void main(String[] args) { String s = "11000010001" ; int n = s.length(); System.out.println(maxLen(s, n)); } } |
Python
MAX = 100 # Returns length of substring which is # having maximum difference of number # of 0s and number of 1s def maxLen(s, n): all_zeros = True all_ones = True for i in range (n): if s[i] = = '0' : all_ones = False else : all_zeros = False if all_zeros or all_ones: return - 1 arr = [ 0 ] * MAX for i in range (n): arr[i] = 1 if s[i] = = '0' else - 1 dp = [[ - 1 for _ in range ( 3 )] for _ in range ( MAX )] # Initializing base case values dp[n][ 0 ] = dp[n][ 1 ] = dp[n][ 2 ] = 0 # Computing DP values from bottom up for i in range (n - 1 , - 1 , - 1 ): for st in range ( 3 ): if st = = 0 : dp[i][st] = max (arr[i] + dp[i + 1 ][ 1 ], dp[i + 1 ][ 0 ]) elif st = = 1 : dp[i][st] = max (arr[i] + dp[i + 1 ][ 1 ], 0 ) else : dp[i][st] = max (arr[i] + dp[i + 1 ][ 1 ], dp[i + 1 ][ 2 ]) # Returning the maximum length of substring with difference # between 0's and 1's equal to the maximum value of dp return dp[ 0 ][ 0 ] # Driver code if __name__ = = '__main__' : s = "11000010001" n = len (s) print (maxLen(s, n)) |
C#
using System; class GFG { // Returns length of substring which is // having maximum difference of number // of 0s and number of 1s static int maxLen( string s, int n) { // Check if all characters are either 0 or 1 bool all_zeros = true , all_ones = true ; for ( int i = 0; i < n; i++) { if (s[i] == '0' ) all_ones = false ; else all_zeros = false ; } if (all_zeros || all_ones) return -1; // Convert string to an array of integers int [] arr = new int [100]; for ( int i = 0; i < n; i++) arr[i] = (s[i] == '0' ? 1 : -1); // Initialize DP array with -1 int [, ] dp = new int [100, 3]; for ( int i = n - 1; i >= 0; i--) { for ( int st = 0; st <= 2; st++) { if (st == 0) dp[i, st] = Math.Max(arr[i] + dp[i + 1, 1], dp[i + 1, 0]); else if (st == 1) dp[i, st] = Math.Max( arr[i] + dp[i + 1, 1], 0); else dp[i, st] = Math.Max(arr[i] + dp[i + 1, 1], dp[i + 1, 2]); } } // Return the maximum length of substring with // difference between 0's and 1's equal to the // maximum value of dp return dp[0, 0]; } // Driver code public static void Main() { string s = "11000010001" ; int n = s.Length; Console.WriteLine(maxLen(s, n)); } } |
Javascript
// Javascript implementation of given problem MAX = 100 // Returns length of substring which is // having maximum difference of number // of 0s and number of 1s function maxLen(s, n) { all_zeros = true all_ones = true for (i = 0; i < n; i++) { if (s[i] == '0' ) { all_ones = false } else { all_zeros = false } } if (all_zeros || all_ones) { return -1 } var arr = new Array(MAX); for (i = 0; i < n; i++) { if (s[i] == '0' ) { arr[i] = 1; } else { arr[i] = -1; } } var dp = new Array(MAX); for ( var i = 0; i < MAX; i++) { dp[i] = new Array(3); for ( var j = 0; j < 3; j++) { dp[i][j] = -1; } } // Initializing base case values dp[n][0] = dp[n][1] = dp[n][2] = 0 // Computing DP values from bottom up for (i = n - 1; i >= 0; i--) { for (st = 0; st < 3; st++) { if (st == 0) { dp[i][st] = Math.max(arr[i] + dp[i + 1][1], dp[i + 1][0]) } else if (st == 1) { dp[i][st] = Math.max(arr[i] + dp[i + 1][1], 0) } else { dp[i][st] = Math.max(arr[i] + dp[i + 1][1], dp[i + 1][2]) } } } // Returning the maximum length of substring with difference // between 0's and 1's equal to the maximum value of dp return dp[0][0] } // Driver code s = "11000010001" n = s.length; console.log(maxLen(s, n)) // This code is contributed by Tapesh(tapeshdua420) |
6
Time Complexity: O(2*len(s)),
Auxiliary Space: O(MAX*3) , MAX = 100
Maximum difference of zeros and ones in binary string | Set 2 (O(n) time)