Minimum number of operations required to sum to binary string S
Given a binary string, S. Find the minimum number of operations required to be performed on the number zero to convert it to the number represented by S.
It is allowed to perform operations of 2 types:
Note: Start performing operations on 0.
Examples:
Input : 100
Output : 1
Explanation: We just perform a single operation, i.e Add 4 (2^2)
Input : 111
Output : 2
Explanation: We perform the following two operations:
1) Add 8(2^3)
2) Subtract 1(2^0)
The idea is to use Dynamic Programming to solve this problem.
Note: In the below analysis, we considered that all binary strings are represented from LSB to MSB (from LHS to RHS) i.e 2(Binary form: “10”) is represented as “01”.
Let the given binary string be S.
Let dp[i][0] represent the minimum number of operations required to make a binary string R such that R[0…i] is the same as S[0…i] and R[i+1…] = “00..0”
Similarly, let dp[i][1] represent the minimum number of operations required to make a binary string R such that R[0…i] is the same as S[0…i] and R[i+1…] = “11..1”
If Si is ‘0’, then dp[i][0] = dp[i – 1][0]. Since we do not require any additional operations. Now we consider the value of dp[i][1], which is a bit trickier. For dp[i][1], we can either make our transition from dp[i – 1][1] by just making the ith character of the string formed by dp[i-1][1], ‘0’. Since earlier this, the ith character was “1”. We just need to subtract 2i from the string represented by dp[i-1][0]. Thus, we perform one operation other than the ones represented by dp[i-1][0].
The other transition could be from dp[i-1][0]. Let dp[i-1][1] represent the string R. Then we need to keep R[i] = 0 as it already is but R[i + 1…..] which is currently “000..0”, needs to be changed to “111…1”, this can be done by subtracting 2(i+1) from R. Thus we just need one operation other than the ones represented by dp[i-1][0].
Similar is the case when Si is ‘1’.
The final answer is the one represented by dp[l-1][0], where l is the length of the binary string S.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int findMinOperations(string S)
{
reverse(S.begin(), S.end());
int n = S.length();
int dp[n + 1][2];
if (S[0] == '0' ) {
dp[0][0] = 0;
}
else {
dp[0][0] = 1;
}
dp[0][1] = 1;
for ( int i = 1; i < n; i++) {
if (S[i] == '0' ) {
dp[i][0] = dp[i - 1][0];
dp[i][1] = 1 + min(dp[i - 1][1], dp[i - 1][0]);
}
else {
dp[i][1] = dp[i - 1][1];
dp[i][0] = 1 + min(dp[i - 1][0], dp[i - 1][1]);
}
}
return dp[n - 1][0];
}
int main()
{
string S = "100" ;
cout << findMinOperations(S) << endl;
S = "111" ;
cout << findMinOperations(S) << endl;
return 0;
}
|
Java
class GFG
{
static int findMinOperations(String S)
{
S = reverse(S);
int n = S.length();
int dp[][] = new int [n + 1 ][ 2 ];
if (S.charAt( 0 ) == '0' )
{
dp[ 0 ][ 0 ] = 0 ;
}
else
{
dp[ 0 ][ 0 ] = 1 ;
}
dp[ 0 ][ 1 ] = 1 ;
for ( int i = 1 ; i < n; i++)
{
if (S.charAt(i) == '0' )
{
dp[i][ 0 ] = dp[i - 1 ][ 0 ];
dp[i][ 1 ] = 1 + Math.min(dp[i - 1 ][ 1 ], dp[i - 1 ][ 0 ]);
}
else
{
dp[i][ 1 ] = dp[i - 1 ][ 1 ];
dp[i][ 0 ] = 1 + Math.min(dp[i - 1 ][ 0 ], dp[i - 1 ][ 1 ]);
}
}
return dp[n - 1 ][ 0 ];
}
static String reverse(String input)
{
char [] temparray = input.toCharArray();
int left, right = 0 ;
right = temparray.length - 1 ;
for (left = 0 ; left < right; left++, right--)
{
char temp = temparray[left];
temparray[left] = temparray[right];
temparray[right] = temp;
}
return String.valueOf(temparray);
}
public static void main(String[] args)
{
String S = "100" ;
System.out.println(findMinOperations(S));
S = "111" ;
System.out.println(findMinOperations(S));
}
}
|
Python3
def findMinOperations(S) :
S = S[: : - 1 ]
n = len (S)
dp = [[ 0 ] * 2 ] * (n + 1 )
if (S[ 0 ] = = '0' ) :
dp[ 0 ][ 0 ] = 0
else :
dp[ 0 ][ 0 ] = 1
dp[ 0 ][ 1 ] = 1
for i in range ( 1 , n) :
if (S[i] = = '0' ) :
dp[i][ 0 ] = dp[i - 1 ][ 0 ]
dp[i][ 1 ] = 1 + min (dp[i - 1 ][ 1 ],
dp[i - 1 ][ 0 ])
else :
dp[i][ 1 ] = dp[i - 1 ][ 1 ];
dp[i][ 0 ] = 1 + min (dp[i - 1 ][ 0 ],
dp[i - 1 ][ 1 ])
return dp[n - 1 ][ 0 ]
if __name__ = = "__main__" :
S = "100"
print (findMinOperations(S))
S = "111" ;
print (findMinOperations(S))
|
C#
using System;
class GFG
{
static int findMinOperations(String S)
{
S = reverse(S);
int n = S.Length;
int [,]dp = new int [n + 1, 2];
if (S[0] == '0' )
{
dp[0, 0] = 0;
}
else
{
dp[0, 0] = 1;
}
dp[0, 1] = 1;
for ( int i = 1; i < n; i++)
{
if (S[i] == '0' )
{
dp[i, 0] = dp[i - 1, 0];
dp[i, 1] = 1 + Math.Min(dp[i - 1, 1], dp[i - 1, 0]);
}
else
{
dp[i, 1] = dp[i - 1, 1];
dp[i, 0] = 1 + Math.Min(dp[i - 1, 0], dp[i - 1, 1]);
}
}
return dp[n - 1, 0];
}
static String reverse(String input)
{
char [] temparray = input.ToCharArray();
int left, right = 0;
right = temparray.Length - 1;
for (left = 0; left < right; left++, right--)
{
char temp = temparray[left];
temparray[left] = temparray[right];
temparray[right] = temp;
}
return String.Join( "" ,temparray);
}
public static void Main()
{
String S = "100" ;
Console.WriteLine(findMinOperations(S));
S = "111" ;
Console.WriteLine(findMinOperations(S));
}
}
|
Javascript
<script>
function findMinOperations(S)
{
S = reverse(S);
let n = S.length;
let dp = new Array(n + 1);
for (let i=0;i<dp.length;i++)
{
dp[i]= new Array(2);
for (let j=0;j<2;j++)
{
dp[i][j]=0;
}
}
if (S[0] == '0' )
{
dp[0][0] = 0;
}
else
{
dp[0][0] = 1;
}
dp[0][1] = 1;
for (let i = 1; i < n; i++)
{
if (S[i] == '0' )
{
dp[i][0] = dp[i - 1][0];
dp[i][1] = 1 + Math.min(dp[i - 1][1], dp[i - 1][0]);
}
else
{
dp[i][1] = dp[i - 1][1];
dp[i][0] = 1 + Math.min(dp[i - 1][0], dp[i - 1][1]);
}
}
return dp[n - 1][0];
}
function reverse(input)
{
let temparray = input.split( "" );
let left, right = 0;
right = temparray.length - 1;
for (left = 0; left < right; left++, right--)
{
let temp = temparray[left];
temparray[left] = temparray[right];
temparray[right] = temp;
}
return (temparray).join( "" );
}
let S = "100" ;
document.write(findMinOperations(S)+ "<br>" );
S = "111" ;
document.write(findMinOperations(S)+ "<br>" );
</script>
|
PHP
<?php
function findMinOperations( $S )
{
$p = strrev ( $S );
$n = strlen ( $p );
$dp = array_fill (0, $n + 1, array_fill (0,2,NULL));
if ( $p [0] == '0' ) {
$dp [0][0] = 0;
}
else {
$dp [0][0] = 1;
}
$dp [0][1] = 1;
for ( $i = 1; $i < $n ; $i ++) {
if ( $p [ $i ] == '0' ) {
$dp [ $i ][0] = $dp [ $i - 1][0];
$dp [ $i ][1] = 1 + min( $dp [ $i - 1][1], $dp [ $i - 1][0]);
}
else {
$dp [ $i ][1] = $dp [ $i - 1][1];
$dp [ $i ][0] = 1 + min( $dp [ $i - 1][0], $dp [ $i - 1][1]);
}
}
return $dp [ $n - 1][0];
}
$S = "100" ;
echo findMinOperations( $S ). "\n" ;
$S = "111" ;
echo findMinOperations( $S ). "\n" ;
return 0;
?>
|
Time Complexity: O(n)
Auxiliary Space: O(n)
Efficient approach : Space optimization O(1)
In previous approach we the current value dp[i] is only depend upon the previous 2 values i.e. dp[i-1][0] and dp[i-1][1]. So to optimize the space we can keep track of previous and current values by the help of variables dp0 and dp1 which will reduce the space complexity from O(N) to O(1).
Implementation Steps:
- Create 2 variables dp0, dp1 to keep track of previous values of DP.
- Initialize base case :- if( s[0] = ‘0’ ) then dp0 = 0 else dp[0] = 1 and dp1 = 1.
- Iterate over subproblem using loop.
- Create a variable temp for transition from dp[i – 1][0].
- After every iteration update dp0 and dp1 for further iterations.
- At last return dp0.
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
int findMinOperations(string S)
{
reverse(S.begin(), S.end());
int n = S.length();
int dp0, dp1;
if (S[0] == '0' ) {
dp0 = 0;
}
else {
dp0 = 1;
}
dp1 = 1;
for ( int i = 1; i < n; i++) {
if (S[i] == '0' ) {
int temp = dp0;
dp0 = temp;
dp1 = 1 + min(dp1, temp);
}
else {
int temp = dp1;
dp1 = temp;
dp0 = 1 + min(dp0, temp);
}
}
return dp0;
}
int main()
{
string S = "100" ;
cout << findMinOperations(S) << endl;
S = "111" ;
cout << findMinOperations(S) << endl;
return 0;
}
|
Java
public class MinOperations {
static int findMinOperations(String S) {
char [] arr = S.toCharArray();
int n = arr.length;
for ( int i = 0 ; i < n / 2 ; i++) {
char temp = arr[i];
arr[i] = arr[n - 1 - i];
arr[n - 1 - i] = temp;
}
int dp0, dp1;
if (arr[ 0 ] == '0' ) {
dp0 = 0 ;
} else {
dp0 = 1 ;
}
dp1 = 1 ;
for ( int i = 1 ; i < n; i++) {
if (arr[i] == '0' ) {
int temp = dp0;
dp0 = temp;
dp1 = 1 + Math.min(dp1, temp);
} else {
int temp = dp1;
dp1 = temp;
dp0 = 1 + Math.min(dp0, temp);
}
}
return dp0;
}
public static void main(String[] args) {
String S = "100" ;
System.out.println(findMinOperations(S));
S = "111" ;
System.out.println(findMinOperations(S));
}
}
|
Python
def findMinOperations(S):
S = S[:: - 1 ]
n = len (S)
dp0, dp1 = 0 , 1
if S[ 0 ] = = '0' :
dp0 = 0
else :
dp0 = 1
dp1 = 1
for i in range ( 1 , n):
if S[i] = = '0' :
temp = dp0
dp0 = temp
dp1 = 1 + min (dp1, temp)
else :
temp = dp1
dp1 = temp
dp0 = 1 + min (dp0, temp)
return dp0
if __name__ = = '__main__' :
S = "100"
print (findMinOperations(S))
S = "111"
print (findMinOperations(S))
|
C#
using System;
class Program
{
static int FindMinOperations( string S)
{
char [] charArray = S.ToCharArray();
Array.Reverse(charArray);
string reversedS = new string (charArray);
int n = reversedS.Length;
int dp0, dp1;
if (reversedS[0] == '0' )
{
dp0 = 0;
}
else
{
dp0 = 1;
}
dp1 = 1;
for ( int i = 1; i < n; i++)
{
if (reversedS[i] == '0' )
{
int temp = dp0;
dp0 = temp;
dp1 = 1 + Math.Min(dp1, temp);
}
else
{
int temp = dp1;
dp1 = temp;
dp0 = 1 + Math.Min(dp0, temp);
}
}
return dp0;
}
static void Main()
{
string S = "100" ;
Console.WriteLine(FindMinOperations(S));
S = "111" ;
Console.WriteLine(FindMinOperations(S));
}
}
|
Javascript
function findMinOperations(S) {
S = S.split( '' ).reverse().join( '' );
const n = S.length;
let dp0, dp1;
if (S[0] === '0' ) {
dp0 = 0;
} else {
dp0 = 1;
}
dp1 = 1;
for (let i = 1; i < n; i++) {
if (S[i] === '0' ) {
const temp = dp0;
dp0 = temp;
dp1 = 1 + Math.min(dp1, temp);
} else {
const temp = dp1;
dp1 = temp;
dp0 = 1 + Math.min(dp0, temp);
}
}
return dp0;
}
const S1 = "100" ;
console.log(findMinOperations(S1));
const S2 = "111" ;
console.log(findMinOperations(S2));
|
Time Complexity: O(n)
Auxiliary Space: O(1)
Last Updated :
11 Oct, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...