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 ithposition 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 ithindex.
- 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 ithindex in the map.
- If prefixSum has already occurred then,
Below is the implementation of the above approach.
// 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;
} |
/*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. |
# 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# 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 |
<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> |
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