Open In App

Maximum difference of zeros and ones in binary string

Last Updated : 06 Jul, 2023
Comments
Improve
Suggest changes
Like Article
Like
Report

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> 

Output
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)

Output
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)


Next Article

Similar Reads