Longest balanced binary substring with equal count of 1s and 0s - GeeksforGeeks

06 Dec, 2021
Given a binary string str[] of size N. The task is to find the longest balanced substring. A substring is balanced if it contains an equal number of 0 and 1.
Examples:  
Input: str = “110101010”Output: 10101010Explanation: The formed substring contain equal count of 1 and 0 i.e, count of 1 and 0 is same equal to 4.
Input: str = “0000”Output: -1
Naive Approach: A simple solution is to use two nested loops to generate every substring. And a third loop to count a number of 0s and 1s in the current substring. Then print the longest substring among them. Time Complexity: O(N^3)Auxiliary Space: O(1)
Efficient solution: With the help of precomputation, store the difference between the count of 0s and the count of 1s from start till current index. This difference can then be used to determine the longest substring with equal 0s and 1s, as the longest distance between any duplicate values in the difference array. Use a Map-based hashing to do precomputation. Follow the steps below to solve the problem:
Initialize the map<int, int> m[].
Set the value of m[0] as -1.
Initialize the variables count_0, count_1, res, start and end.
Traverse the string str[] using the variable i and perform the following tasks:Keep the track of counts of 1s and 0s as count_1 and count_0 respectively.See if the current difference between count_1 and count_0 is already there in the map m[] or not. If yes, then perform the following tasks:The substring from the previous appearance and current index has same number of 0s and 1s.If the current found substring’s length is greater than res then set the found substring as the answer so far.If it is appearing for the first time, store the current difference and the current index in the map i.e, m[count_1 – count_0] equals i.
Keep the track of counts of 1s and 0s as count_1 and count_0 respectively.
See if the current difference between count_1 and count_0 is already there in the map m[] or not. If yes, then perform the following tasks:The substring from the previous appearance and current index has same number of 0s and 1s.If the current found substring’s length is greater than res then set the found substring as the answer so far.
The substring from the previous appearance and current index has same number of 0s and 1s.
If the current found substring’s length is greater than res then set the found substring as the answer so far.
If it is appearing for the first time, store the current difference and the current index in the map i.e, m[count_1 – count_0] equals i.
If count_0 and count_1 are both 0, then print -1.
Otherwise, print the substring from start to end.
Below is the implementation of the above approach.
C++
Java
Python3
C#
Javascript
// C++ for finding length// of longest balanced substring#include <bits/stdc++.h>using namespace std; // Returns length of the longest substring// with equal number of zeros and ones.string stringLen(string str){     // Create a map to store differences    // between counts of 1s and 0s.    map<int, int> m;     // Initially difference is 0.    m[0] = -1;     int count_0 = 0, count_1 = 0;    int start, end, res = 0;    for (int i = 0; i < str.size(); i++) {         // Keeping track of counts of        // 0s and 1s.        if (str[i] == '0')            count_0++;        else            count_1++;         // If difference between current counts        // already exists, then substring between        // previous and current index has same        // no. of 0s and 1s. Update result if this        // substring is more than current result.        if (m.find(count_1 - count_0) != m.end()) {             if ((i - m[count_1 - count_0]) > res) {                 start = m.find(                             count_1 - count_0)                            ->second;                end = i;                res = end - start;            }        }         // If current difference        // is seen first time.        else            m[count_1 - count_0] = i;    }     if (count_0 == 0 || count_1 == 0)        return "-1";     // Return the substring    // between found indices    return str.substr(start + 1, end + 1);} // Driver Codeint main(){    string str = "110101010";    cout << stringLen(str);    return 0;}
// Java code for the above approachimport java.io.*;class GFG{   // Returns length of the longest substring  // with equal number of zeros and ones.  static String stringLen(String str)  {     // Create a map to store differences    // between counts of 1s and 0s.    int [] m = new int[100000];     // Initially difference is 0.    m[0] = -1;     int count_0 = 0; int count_1 = 0;    int start = 0; int end = 0; int res = 0;    for (int i = 0; i < str.length(); i++) {       // Keeping track of counts of      // 0s and 1s.      if (str.charAt(i) == '0')        count_0++;      else        count_1++;       // If difference between current counts      // already exists, then substring between      // previous and current index has same      // no. of 0s and 1s. Update result if this      // substring is more than current result.      if (m[count_1 - count_0]!= 0) {         if ((i - m[count_1 - count_0]) > res) {           start = m[count_1 - count_0];           end = i;          res = end - start;        }      }       // If current difference      // is seen first time.      else        m[count_1 - count_0] = i;    }     if (count_0 == 0 || count_1 == 0)      return "-1";     // Return the substring    // between found indices    return str.substring(start , end + 2);  }   // Driver Code  public static void main (String[] args)  {    String str = "110101010";     System.out.println(stringLen(str));  }} // This code is contributed by Potta Lokesh
# Python for finding length# of longest balanced substring # Returns length of the longest substring# with equal number of zeros and ones.def stringLen (str) :     # Create a map to store differences    # between counts of 1s and 0s.    m = {}     # Initially difference is 0.    m[0] = -1     count_0 = 0    count_1 = 0    res = 0    for i in range(len(str)):         # Keeping track of counts of        # 0s and 1s.        if (str[i] == '0'):            count_0 += 1        else:            count_1 += 1         # If difference between current counts        # already exists, then substring between        # previous and current index has same        # no. of 0s and 1s. Update result if this        # substring is more than current result.        if ((count_1 - count_0) in m):             if ((i - m[count_1 - count_0]) > res):                 start = m[(count_1 - count_0)]                end = i                res = end - start                     # If current difference        # is seen first time.        else:            m[count_1 - count_0] = i         if (count_0 == 0 or count_1 == 0):        return "-1"     # Return the substring    # between found indices    return str[start + 1 : start + 1 + end + 1] # Driver Codestr = "110101010"print(stringLen(str)) # This code is contributed by Saurabh Jaiswal
// C# code for the above approachusing System;using System.Collections;using System.Collections.Generic; class GFG{   // Returns length of the longest substring  // with equal number of zeros and ones.  static string stringLen(string str)  {     // Create a map to store differences    // between counts of 1s and 0s.    int []m = new int[100000];     // Initially difference is 0.    m[0] = -1;     int count_0 = 0; int count_1 = 0;    int start = 0; int end = 0; int res = 0;    for (int i = 0; i < str.Length; i++) {       // Keeping track of counts of      // 0s and 1s.      if (str[i] == '0')        count_0++;      else        count_1++;       // If difference between current counts      // already exists, then substring between      // previous and current index has same      // no. of 0s and 1s. Update result if this      // substring is more than current result.      if (m[count_1 - count_0]!= 0) {         if ((i - m[count_1 - count_0]) > res) {           start = m[count_1 - count_0];           end = i;          res = end - start;        }      }       // If current difference      // is seen first time.      else        m[count_1 - count_0] = i;    }     if (count_0 == 0 || count_1 == 0)      return "-1";     // Return the substring    // between found indices    return str.Substring(start, end - start + 2);  }   // Driver Code  public static void Main ()  {    string str = "110101010";     Console.Write(stringLen(str));  }} // This code is contributed by Samim Hossain Mondal.
<script>    // JavaScript for finding length    // of longest balanced substring     // Returns length of the longest substring    // with equal number of zeros and ones.    const stringLen = (str) => {         // Create a map to store differences        // between counts of 1s and 0s.        let m = {};         // Initially difference is 0.        m[0] = -1;         let count_0 = 0, count_1 = 0;        let start, end, res = 0;        for (let i = 0; i < str.length; i++) {             // Keeping track of counts of            // 0s and 1s.            if (str[i] == '0')                count_0++;            else                count_1++;             // If difference between current counts            // already exists, then substring between            // previous and current index has same            // no. of 0s and 1s. Update result if this            // substring is more than current result.            if ((count_1 - count_0) in m) {                 if ((i - m[count_1 - count_0]) > res) {                     start = m[(count_1 - count_0)];                    end = i;                    res = end - start;                }            }             // If current difference            // is seen first time.            else                m[count_1 - count_0] = i;        }         if (count_0 == 0 || count_1 == 0)            return "-1";         // Return the substring        // between found indices        return str.substring(start + 1, start + 1 + end + 1);    }     // Driver Code    let str = "110101010";    document.write(stringLen(str));     // This code is contributed by rakeshsahni</script>
10101010
Time Complexity: O(N)Auxiliary Space: O(N)
rakeshsahni
lokeshpotta20
_saurabh_jaiswal
samim2000
binary-string
Arrays
Bit Magic
Hash
Mathematical
Strings
Arrays
Hash
Strings
Mathematical
Bit Magic
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Comments
Old Comments
Window Sliding Technique
Program to find sum of elements in a given array
Reversal algorithm for array rotation
Find duplicates in O(n) time and O(1) extra space | Set 1
Trapping Rain Water
Bitwise Operators in C/C++
Left Shift and Right Shift Operators in C/C++
Travelling Salesman Problem | Set 1 (Naive and Dynamic Programming)
Cyclic Redundancy Check and Modulo-2 Division
Count set bits in an integer