Split a binary string into substrings with equal 0s and 1s

Last Updated : 10 May, 2026

Given binary string s . find the maximum number of substrings it can be splitted into such that all substrings have equal number of 0s and 1s. If it is not possible to split s satisfying the conditions then return -1.

Examples: 

Input: s = "0100110101" 
Output:
Explanation: The required substrings are "01", "0011", "01" and "01".

Input: s = "0111100010" 
Output: 3
Explanation: The required substrings are "01", "111000" and "10"

Try It Yourself
redirect icon

Using Stack - O(n) Time O(n) Space

The idea is to use a stack to simulate cancellation of opposite characters (0 and 1), similar to balanced parentheses.

  • We push characters into the stack and whenever a different character is encountered, we pop from the stack.
  • Whenever the stack becomes empty, it indicates that a balanced substring is formed, so we increment the count.
  • After processing the entire string, if the stack is empty, we return the count; otherwise we return -1.
C++
#include <bits/stdc++.h>
using namespace std;

int maxSubStr(string &s)
{
    // similar to balanced parenthesis approach
    // we push same elements into stack and pop when different element appears
    // whenever stack becomes empty, we found one balanced substring
    int ans = 0;
    int i = 0;

    stack<char> st;

    // push first character
    st.push(s[i]);
    i++;

    // traverse the string
    while (i < s.size())
    {

        // pop when current char is different from stack top
        while (i < s.size() && st.size() && (st.top() != s[i]))
        {
            st.pop();
            i++;
        }

        // if stack becomes empty, one balanced substring is found
        if (st.empty())
        {
            ans++;
        }

        // push characters when stack is empty OR same char repeats
        while ((i < s.size()) && (st.empty() || st.top() == s[i]))
        {
            st.push(s[i]);
            i++;
        }
    }

    // if stack is empty at end → fully balanced
    if (st.empty())
        return ans;

    // otherwise not possible
    return -1;
}

// Driver code
int main() {
    string s = "0100110101";
    
    cout << maxSubStr(s);
    
    return 0;
}
C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <ctype.h>
#include <limits.h>

#define MAX 100

int maxSubStr(char *s)
{
    // similar to balanced parenthesis approach
    // we push same elements into stack and pop when different element appears
    // whenever stack becomes empty, we found one balanced substring

    int ans = 0;
    int i = 0;

    char st[MAX];
    int top = -1;

    // push first character
    st[++top] = s[i];
    i++;

    // traverse the string
    while (i < strlen(s))
    {
        // pop when current char is different from stack top
        while (i < strlen(s) && top!= -1 && st[top]!= s[i])
        {
            top--;
            i++;
        }

        // if stack becomes empty, one balanced substring is found
        if (top == -1)
        {
            ans++;
        }

        // push characters when stack is empty OR same char repeats
        while ((i < strlen(s)) && (top == -1 || st[top] == s[i]))
        {
            st[++top] = s[i];
            i++;
        }
    }

    // if stack is empty at end → fully balanced
    if (top == -1)
        return ans;

    // otherwise not possible
    return -1;
}

// Driver code
int main() {
    char s[] = "0100110101";

    printf("%d", maxSubStr(s));

    return 0;
}
Java
import java.util.*;

public class GfG {
    // similar to balanced parenthesis approach
    // we push same elements into stack and pop when different element appears
    // whenever stack becomes empty, we found one balanced substring
    public static int maxSubStr(String s) {
        int ans = 0;
        int i = 0;

        Stack<Character> st = new Stack<>();

        // push first character
        st.push(s.charAt(i));
        i++;

        // traverse the string
        while (i < s.length()) {
            // pop when current char is different from stack top
            while (i < s.length() &&!st.isEmpty() && st.peek()!= s.charAt(i)) {
                st.pop();
                i++;
            }

            // if stack becomes empty, one balanced substring is found
            if (st.isEmpty()) {
                ans++;
            }

            // push characters when stack is empty OR same char repeats
            while (i < s.length() && (st.isEmpty() || st.peek() == s.charAt(i))) {
                st.push(s.charAt(i));
                i++;
            }
        }

        // if stack is empty at end → fully balanced
        if (st.isEmpty())
            return ans;

        // otherwise not possible
        return -1;
    }

    // Driver code
    public static void main(String[] args) {
        String s = "0100110101";

        System.out.println(maxSubStr(s));
    }
}
Python
def maxSubStr(s):
    # similar to balanced parenthesis approach
    # we push same elements into stack and pop when different element appears
    # whenever stack becomes empty, we found one balanced substring

    ans = 0
    i = 0

    st = []

    # push first character
    st.append(s[i])
    i += 1

    # traverse the string
    while i < len(s):

        # pop when current char is different from stack top
        while i < len(s) and st and st[-1]!= s[i]:
            st.pop()
            i += 1

        # if stack becomes empty, one balanced substring is found
        if not st:
            ans += 1

        # push characters when stack is empty OR same char repeats
        while i < len(s) and (not st or st[-1] == s[i]):
            st.append(s[i])
            i += 1

    # if stack is empty at end → fully balanced
    if not st:
        return ans

    # otherwise not possible
    return -1

# Driver Code
if __name__ == "__main__":
    s = "0100110101"
    print(maxSubStr(s))
C#
using System;
using System.Collections.Generic;

class GfG
{
    public int maxSubStr(string s)
    {
        // similar to balanced parenthesis approach
        // we push same elements into stack and pop when different element appears
        // whenever stack becomes empty, we found one balanced substring

        int ans = 0;
        int i = 0;

        Stack<char> st = new Stack<char>();

        // push first character
        st.Push(s[i]);
        i++;

        // traverse the string
        while (i < s.Length)
        {
            // pop when current char is different from stack top
            while (i < s.Length && st.Count > 0 && st.Peek() != s[i])
            {
                st.Pop();
                i++;
            }

            // if stack becomes empty, one balanced substring is found
            if (st.Count == 0)
            {
                ans++;
            }

            // push characters when stack is empty OR same char repeats
            while (i < s.Length && (st.Count == 0 || st.Peek() == s[i]))
            {
                st.Push(s[i]);
                i++;
            }
        }

        // if stack is empty at end → fully balanced
        if (st.Count == 0)
            return ans;

        // otherwise not possible
        return -1;
    }

    public static void Main()
    {
        string s = "0100110101";

        GfG obj = new GfG();

        Console.WriteLine(obj.maxSubStr(s));
    }
}
JavaScript
function maxSubStr(s) {
    // similar to balanced parenthesis approach
    // we push same elements into stack and pop when different element appears
    // whenever stack becomes empty, we found one balanced substring

    let ans = 0;
    let i = 0;

    let st = [];

    // push first character
    st.push(s[i]);
    i++;

    // traverse the string
    while (i < s.length) {

        // pop when current char is different from stack top
        while (i < s.length && st.length && (st[st.length - 1]!== s[i])) {
            st.pop();
            i++;
        }

        // if stack becomes empty, one balanced substring is found
        if (st.length === 0) {
            ans++;
        }

        // push characters when stack is empty OR same char repeats
        while ((i < s.length) && (st.length === 0 || st[st.length - 1] === s[i])) {
            st.push(s[i]);
            i++;
        }
    }

    // if stack is empty at end → fully balanced
    if (st.length === 0)
        return ans;

    // otherwise not possible
    return -1;
}

// Driver code
let s = '0100110101';

console.log(maxSubStr(s));

Output
4

Time Complexity: O(n)
Space Complexity: O(n)

Using Simple Traversal - O(n) Time O(1) Space

The idea is to traverse the string while counting 0s and 1s. Whenever both counts become equal, a balanced substring is found, so we increment the count. After traversal, if the total number of 0s and 1s are not equal, we return -1; otherwise, we return the count.

C++
#include <bits/stdc++.h>
using namespace std;

// Function to return the count
// of maximum substrings
// can be divided into
int maxSubStr(string &s)
{

    int n = s.length();

    // To store the count of 0s and 1s
    int count0 = 0, count1 = 0;

    // To store the count of maximum substrings
    int cnt = 0;

    for (int i = 0; i < n; i++)
    {
        if (s[i] == '0')
        {
            count0++;
        }
        else
        {
            count1++;
        }

        if (count0 == count1)
        {
            cnt++;
        }
    }

    // If overall count not equal, return -1
    if (count0 != count1)
    {
        return -1;
    }

    return cnt;
}

// Driver code
int main() {
    string s = "0100110101";

    cout << maxSubStr(s);

    return 0;
}
C
#include <stdio.h>
#include <string.h>

// Function to return the count
// of maximum substrings
// can be divided into
int maxSubStr(char *s)
{
    int n = strlen(s);

    // To store the count of 0s and 1s
    int count0 = 0, count1 = 0;

    // To store the count of maximum substrings
    int cnt = 0;

    for (int i = 0; i < n; i++)
    {
        if (s[i] == '0')
        {
            count0++;
        }
        else
        {
            count1++;
        }

        if (count0 == count1)
        {
            cnt++;
        }
    }

    // If overall count not equal, return -1
    if (count0!= count1)
    {
        return -1;
    }

    return cnt;
}

// Driver code
int main() {
    char s[] = "0100110101";

    printf("%d", maxSubStr(s));

    return 0;
}
Java
public class GfG {
    // Function to return the count
    // of maximum substrings
    // can be divided into
    static int maxSubStr(String s)
    {
        int n = s.length();

        // To store the count of 0s and 1s
        int count0 = 0, count1 = 0;

        // To store the count of maximum substrings
        int cnt = 0;

        for (int i = 0; i < n; i++)
        {
            if (s.charAt(i) == '0')
            {
                count0++;
            }
            else
            {
                count1++;
            }

            if (count0 == count1)
            {
                cnt++;
            }
        }

        // If overall count not equal, return -1
        if (count0!= count1)
        {
            return -1;
        }

        return cnt;
    }

    // Driver code
    public static void main(String[] args) {
        String s = "0100110101";

        System.out.println(maxSubStr(s));
    }
}
Python
# Function to return the count
# of maximum substrings
# can be divided into
def maxSubStr(s):
    n = len(s)

    count0 = 0
    count1 = 0
    cnt = 0

    for i in range(n):
        if s[i] == '0':
            count0 += 1
        else:
            count1 += 1

        if count0 == count1:
            cnt += 1

    if count0 != count1:
        return -1

    return cnt


# Driver Code
if __name__ == "__main__":
    s = "0100110101"
    print(maxSubStr(s))
C#
using System;

class GfG {
    
    // Function to return the count
    // of maximum substrings
    // can be divided into
    public int maxSubStr(string s)
    {
        int n = s.Length;

        // To store the count of 0s and 1s
        int count0 = 0, count1 = 0;

        // To store the count of maximum substrings
        int cnt = 0;

        for (int i = 0; i < n; i++)
        {
            if (s[i] == '0')
            {
                count0++;
            }
            else
            {
                count1++;
            }

            if (count0 == count1)
            {
                cnt++;
            }
        }

        // If overall count not equal, return -1
        if (count0 != count1)
        {
            return -1;
        }

        return cnt;
    }

    public static void Main()
    {
        string s = "0100110101";

        GfG obj = new GfG();

        Console.WriteLine(obj.maxSubStr(s));
    }
}
JavaScript
function maxSubStr(s) {
    var n = s.length;

    // To store the count of 0s and 1s
    var count0 = 0, count1 = 0;

    // To store the count of maximum substrings
    var cnt = 0;

    for (var i = 0; i < n; i++) {
        if (s[i] === '0') {
            count0++;
        }
        else {
            count1++;
        }

        if (count0 === count1) {
            cnt++;
        }
    }

    // If overall count not equal, return -1
    if (count0!== count1) {
        return -1;
    }

    return cnt;
}

// Driver code
let s = "0100110101";

console.log(maxSubStr(s));

Output
4

Time Complexity: O(n)
Space Complexity: O(1)

Comment