Minimize removal from front or end to make the Binary String at equilibrium
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++
#include <bits/stdc++.h>
using namespace std;
int minRemoval(string& s)
{
unordered_map< int , int > unmap;
int n = s.size();
int prefixSum = 0;
int result = 0;
for ( int i = 0; i < n; i++) {
prefixSum += ((s[i] == '1' ) ? 1 : -1);
if (prefixSum == 0) {
result = max(result, i + 1);
}
if (unmap.count(prefixSum)) {
result = max(result,
i - unmap[prefixSum]);
}
else {
unmap[prefixSum] = i;
}
}
return n - result;
}
int main()
{
string S = "0111010" ;
int result = minRemoval(S);
cout << result << endl;
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG {
static int minRemoval(String s)
{
HashMap<Integer,Integer> mp = new HashMap<>();
int n = s.length();
int prefixSum = 0 ;
int result = 0 ;
for ( int i = 0 ; i < n; i++) {
prefixSum += ((s.charAt(i) == '1' ) ? 1 : - 1 );
if (prefixSum == 0 ) {
result = Math.max(result, i + 1 );
}
if (mp.containsKey(prefixSum)) {
result = Math.max(result,i - mp.get(prefixSum));
}
else {
mp.put(prefixSum,i);
}
}
return n - result;
}
public static void main (String[] args) {
String S = "0111010" ;
int result = minRemoval(S);
System.out.println(result);
}
}
|
Python3
def minRemoval(s):
mp = {}
n = len (s)
prefixSum = 0
result = 0
for i in range (n):
prefixSum + = 1 if (s[i] = = '1' ) else - 1
if prefixSum is 0 :
result = max (result, i + 1 )
if prefixSum in mp:
result = max (result, i - mp[prefixSum])
else :
mp[prefixSum] = i
return n - result
S = "0111010"
result = minRemoval(S)
print (result)
|
C#
using System;
using System.Collections.Generic;
public class HelloWorld
{
static int minRemoval( string s)
{
Dictionary< int , int > unmap =
new Dictionary< int , int >();
int n = s.Length;
int prefixSum = 0;
int result = 0;
for ( int i = 0; i < n; i++) {
prefixSum += ((s[i] == '1' ) ? 1 : -1);
if (prefixSum == 0) {
result = Math.Max(result, i + 1);
}
if (unmap.ContainsKey(prefixSum)) {
result = Math.Max(result,
i - unmap[prefixSum]);
}
else {
unmap[prefixSum] = i;
}
}
return n - result;
}
public static void Main( string [] args)
{
string S = "0111010" ;
int result = minRemoval(S);
Console.WriteLine(result);
}
}
|
Javascript
<script>
const minRemoval = (s) => {
let unmap = {};
let n = s.length;
let prefixSum = 0;
let result = 0;
for (let i = 0; i < n; i++) {
prefixSum += ((s[i] == '1' ) ? 1 : -1);
if (prefixSum == 0) {
result = Math.max(result, i + 1);
}
if (prefixSum in unmap) {
result = Math.max(result,
i - unmap[prefixSum]);
}
else {
unmap[prefixSum] = i;
}
}
return n - result;
}
let S = "0111010" ;
let result = minRemoval(S);
document.write(result);
</script>
|
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
Share your thoughts in the comments
Please Login to comment...