Open In App

Minimize removal from front or end to make the Binary String at equilibrium

Improve
Improve
Like Article
Like
Save
Share
Report

Given a binary string S of size N, the task is to find the minimum number of removal required either from the start or end position from the binary strings such that the count of ‘0’ and ‘1’ becomes equal in the final string after removal.

Examples:

Input: S = “0111010”
Output: 3
Explanation: Remove 3 elements from the front of given string. 
String after removal will be “1010”, which have equal number of 0’s and 1’s.

Input: S = “01100101”
Output: 0

An approach using the Prefix Sum technique:

The idea to solve this problem is based on the observation that 

For any valid substring where number of 0’s and number of 1’s is equal then the sum of value of the substring will also be zero if we consider the value of character ‘1’s be 1 and ‘0’s be -1

So, the problem statement boils down to finding the length of longest substring where the sum of their value’s that we have assumed would be 0. The remaining part after finding the longest valid substring would be deleted.

Follow the steps below to implement the above idea:

  • Iterate over the length of the given binary string.
  • Create a variable (say, prefixSum) for calculating the prefix Sum from start to ith position and a variable result for storing the length of the longest valid substring.
  • Create a map (say, unmap) for storing the prefix Sum ending at ith index.
  • Calculate the prefixSum by considering the value for characters ‘1’ to 1 and ‘0’ to -1.
  • Check the value of prefixSum:
    • If the value of prefixSum is equal to zero, then update the result with its current substring length.
    • Otherwise, Check if this prefixSum has already occurred previously or not.
      • If prefixSum has already occurred then,
        •  The length of the valid substring would be (i – unmap[prefixSum]) (i.e. If we remove this prefixSum value that has already occurred from the current prefixSum then the value of the remaining substring would result in 0.)
      • Otherwise, store this current prefixSum has occurred at ith index in the map.

Below is the implementation of the above approach.

C++




// C++ code to implement the approach.
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to solve the problem
int minRemoval(string& s)
{
    // Storing prefixSum with index
    // of its first occurrence
    unordered_map<int, int> unmap;
    int n = s.size();
 
    // For storing the prefix Sum
    // ending at ith index
    int prefixSum = 0;
 
    // For keeping the length of
    // longest binary string where
    // number of zero and ones are equal
    int result = 0;
 
    // Iterate over the string
    for (int i = 0; i < n; i++) {
 
        prefixSum += ((s[i] == '1') ? 1 : -1);
 
        if (prefixSum == 0) {
            result = max(result, i + 1);
        }
 
        // Check if prefixSum have
        // previously occurred or not
        if (unmap.count(prefixSum)) {
 
            // Update the result with
            // this valid substring
            result = max(result,
                         i - unmap[prefixSum]);
        }
        else {
 
            // Store this prefixSum has
            // occur at ith index
            // in the map.
            unmap[prefixSum] = i;
        }
    }
 
    // Return the remaining length
    // other than the longest
    // valid substring.
    return n - result;
}
 
// Driver code
int main()
{
    string S = "0111010";
 
    // Function call
    int result = minRemoval(S);
    cout << result << endl;
    return 0;
}


Java




/*package whatever //do not write package name here */
import java.io.*;
import java.util.*;
 
class GFG {
 
  // Function to solve the problem
  static int minRemoval(String s)
  {
 
    // Storing prefixSum with index
    // of its first occurrence
    HashMap<Integer,Integer> mp = new HashMap<>();
    int n = s.length();
 
    // For storing the prefix Sum
    // ending at ith index
    int prefixSum = 0;
 
    // For keeping the length of
    // longest binary string where
    // number of zero and ones are equal
    int result = 0;
 
    // Iterate over the string
    for (int i = 0; i < n; i++) {
 
      prefixSum += ((s.charAt(i) == '1') ? 1 : -1);
 
      if (prefixSum == 0) {
        result = Math.max(result, i + 1);
      }
 
      // Check if prefixSum have
      // previously occurred or not
      if (mp.containsKey(prefixSum)) {
 
        // Update the result with
        // this valid substring
        result = Math.max(result,i - mp.get(prefixSum));
      }
      else {
 
        // Store this prefixSum has
        // occur at ith index
        // in the map.
        mp.put(prefixSum,i);
      }
    }
 
    // Return the remaining length
    // other than the longest
    // valid substring.
    return n - result;
  }
 
  public static void main (String[] args) {
    String S = "0111010";
 
    // Function call
    int result = minRemoval(S);
    System.out.println(result);
  }
}
 
// This code is contributed by aadityaburujwale.


Python3




# Python code for the above approach
 
# Function to solve the problem
def minRemoval(s):
   
    # Storing prefixSum with index of
    # its first occurrence.
    mp = {}
    n = len(s)
 
    # For storing the prefix Sum ending
    # at ith index
    prefixSum = 0
 
    # For keeping the length of longest
    # binary string where number of zero
    # and ones are equal.
    result = 0
 
    # Iterate over the string
    for i in range(n):
        prefixSum += 1 if(s[i] == '1') else -1
 
        if prefixSum is 0:
            result = max(result, i+1)
 
        # Check if prefixSum have previously
        # occurred or not
        if prefixSum in mp:
           
            # Update the result with this
            # valid substring
            result = max(result, i-mp[prefixSum])
        else:
            # Store this prefixSum has occur at
            # ith index in the map.
            mp[prefixSum] = i
 
    # Return the remaining length other
    # than the longest valid substring.
    return n-result
 
S = "0111010"
 
# Function call
result = minRemoval(S)
print(result)
 
# This code is contributed by lokesh.


C#




// C# implementation
 
using System;
using System.Collections.Generic; 
public class HelloWorld
{
  // Function to solve the problem
  static int minRemoval(string s)
  {
    // Storing prefixSum with index
    // of its first occurrence
    //   unordered_map<int, int> unmap;
    Dictionary<int, int> unmap = 
      new Dictionary<int, int>();
 
    int n = s.Length;
 
    // For storing the prefix Sum
    // ending at ith index
    int prefixSum = 0;
 
    // For keeping the length of
    // longest binary string where
    // number of zero and ones are equal
    int result = 0;
 
    // Iterate over the string
    for (int i = 0; i < n; i++) {
 
      prefixSum += ((s[i] == '1') ? 1 : -1);
 
      if (prefixSum == 0) {
        result = Math.Max(result, i + 1);
      }
 
      // Check if prefixSum have
      // previously occurred or not
      if (unmap.ContainsKey(prefixSum)) {
 
        // Update the result with
        // this valid substring
        result = Math.Max(result,
                          i - unmap[prefixSum]);
      }
      else {
 
        // Store this prefixSum has
        // occur at ith index
        // in the map.
        unmap[prefixSum] = i;
      }
    }
 
    // Return the remaining length
    // other than the longest
    // valid substring.
    return n - result;
  }
 
  public static void Main(string[] args)
  {
    string S = "0111010";
 
    // Function call
    int result = minRemoval(S);
    Console.WriteLine(result);
  }
}
 
// this code is contributed by ksam24000


Javascript




<script>
    // JavaScript code to implement the approach.
 
 
    // Function to solve the problem
    const minRemoval = (s) => {
        // Storing prefixSum with index
        // of its first occurrence
        let unmap = {};
        let n = s.length;
 
        // For storing the prefix Sum
        // ending at ith index
        let prefixSum = 0;
 
        // For keeping the length of
        // longest binary string where
        // number of zero and ones are equal
        let result = 0;
 
        // Iterate over the string
        for (let i = 0; i < n; i++) {
 
            prefixSum += ((s[i] == '1') ? 1 : -1);
 
            if (prefixSum == 0) {
                result = Math.max(result, i + 1);
            }
 
            // Check if prefixSum have
            // previously occurred or not
            if (prefixSum in unmap) {
 
                // Update the result with
                // this valid substring
                result = Math.max(result,
                    i - unmap[prefixSum]);
            }
            else {
 
                // Store this prefixSum has
                // occur at ith index
                // in the map.
                unmap[prefixSum] = i;
            }
        }
 
        // Return the remaining length
        // other than the longest
        // valid substring.
        return n - result;
    }
 
    // Driver code
 
    let S = "0111010";
 
    // Function call
    let result = minRemoval(S);
    document.write(result);
 
// This code is contributed by rakeshsahni
 
</script>


Output

3

Time Complexity: O(N), where N is the length of the given binary string.
Auxiliary Space: O(N) // since we are using an unordered_map , in worst case the entire string will be stored hence the auxiliary space turns out to be linear



Last Updated : 23 Jan, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads