Minimum operations to convert given string into all 1s or 0s
Last Updated :
30 Nov, 2023
Given a string S containing 0s and 1s of length N with X, the task is to output the minimum operations required to convert S into either all 1s or 0s. The operation is defined as, taking two different indices i and j (1-based indexing), such that they give equal remainder when dividing from X, then update Si = Si⊕Sj.
Examples:
Input: N = 4, X = 2, S = “1100”
Output: 2
Explanation:
- First operation: i = 1 and j = 3 as (i%X == j%X == 1). So, update S1 = S1⊕S3 = 1. Then S = 1110
- Second operation: i = 2 and j = 4 as (i%X == j%X == 0). So, update S2 = S2⊕S4 = 1. Then S = 1111. Now all the characters are turned into 1. Therefore, the minimum number of operations required is 2.
Input: N = 6, X = 4, S = “100101”
Output: 6
Explanation: It can be verified that, If operations are performed optimally, Then the minimum operations required will be 6.
Approach: Implement the idea below to solve the problem
Idea:
The problem is based on the Bitwise Concept and can be solved using some observations.
XOR of same characters is 0 and XOR of different characters is 1. We can do XOR operations on particular set of characters.
For Example: If X = 2, then we can do XOR on 1st, 3rd, 5th.. or 2nd, 4th, 6th… and so on.
There can be two cases: Either we can make all character to ones or all characters to zeroes.
- If we want to make all characters in a set to 1: then there should to at least one ‘1’ in that set. If not, then it is impossible to make all characters equal to ‘1’.
- If we want to make all characters in a set to 0: then if the number of ‘1’ in that set is even, then the number of operations are half of the number of ‘1’ else we have to add 2 more operations to make the one remaining ‘1’ in that set to ‘0’ using some other ‘0’ in that set by XORing the ‘0’ with ‘1’ two times.
ie. [1,0] -> 1 ^ 0 = 1; [1,1] -> 1 ^ 1 = 0; [0,0].
It takes one operation to convert [1,0] to [1,1] and one operation to convert [1,1] to [0,0]. So, it takes two operations to convert [1,0] to [0,0].
Steps were taken to solve the problem:
- Create a variable let say min1
- Create a boolean array let say vis[] of length N
- Run a loop for i = 0 to i < N and follow below mentioned steps under the scope of loop:
- If (!vis[i])
- one = 0
- zero = 0
- Run a loop for for j = i to j < N with increment j += X and follow below mentioned steps under the scope of loop:
- vis[j] = true
- If (S[j] == 0)
- Else
- If (one == 0)
- min1 = INT_MAX
- break the loop
- Else
- initialize vis[] to new boolean array of same length
- Declare a variable let say min2
- Run a loop for i = 0 to i < N and follow below mentioned steps under the scope of loop:
- If (!vis[i])
- one = 0
- Run a loop for j = i to j < N with incrementing j += X and follow below mentioned steps under the scope of loop:
- vis[j] = true
- If (S[j] == 1)
- If (one % 2 == 0)
- Else
- Output min(min1, min2)
Implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
using namespace std;
void Min_Operations( int N, int X, char S[]) {
int min1 = 0;
vector< bool > vis(N, false );
for ( int i = 0; i < N; i++) {
if (!vis[i]) {
int one = 0;
int zero = 0;
for ( int j = i; j < N; j += X) {
vis[j] = true ;
if (S[j] == '0' )
zero++;
else
one++;
}
if (one == 0) {
min1 = INT_MAX;
break ;
} else
min1 += zero;
}
}
vis = vector< bool >(N, false );
int min2 = 0;
for ( int i = 0; i < N; i++) {
if (!vis[i]) {
int one = 0;
for ( int j = i; j < N; j += X) {
vis[j] = true ;
if (S[j] == '1' )
one++;
}
if (one % 2 == 0)
min2 += one / 2;
else
min2 += (one / 2) + 2;
}
}
cout << min(min1, min2) << endl;
}
int main() {
int N = 4;
int X = 2;
char S[] = "1100" ;
Min_Operations(N, X, S);
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG {
public static void main(String[] args)
{
int N = 4 ;
int X = 2 ;
char [] S = (" 1100 ").toCharArray();
Min_Operations(N, X, S);
}
public static void Min_Operations( int N, int X,
char [] S)
{
int min1 = 0 ;
boolean [] vis = new boolean [N];
for ( int i = 0 ; i < N; i++) {
if (!vis[i]) {
int one = 0 ;
int zero = 0 ;
for ( int j = i; j < N; j += X) {
vis[j] = true ;
if (S[j] == '0' )
zero++;
else
one++;
}
if (one == 0 ) {
min1 = Integer.MAX_VALUE;
break ;
}
else
min1 += zero;
}
}
vis = new boolean [N];
int min2 = 0 ;
for ( int i = 0 ; i < N; i++) {
if (!vis[i]) {
int one = 0 ;
for ( int j = i; j < N; j += X) {
vis[j] = true ;
if (S[j] == '1' )
one++;
}
if (one % 2 == 0 )
min2 += one / 2 ;
else
min2 += (one / 2 ) + 2 ;
}
}
System.out.println(Math.min(min1, min2));
}
}
|
Python3
def min_operations(N, X, S):
min1 = 0
vis = [ False ] * N
for i in range (N):
if not vis[i]:
one = 0
zero = 0
for j in range (i, N, X):
vis[j] = True
if S[j] = = '0' :
zero + = 1
else :
one + = 1
if one = = 0 :
min1 = float ( 'inf' )
break
else :
min1 + = zero
vis = [ False ] * N
min2 = 0
for i in range (N):
if not vis[i]:
one = 0
for j in range (i, N, X):
vis[j] = True
if S[j] = = '1' :
one + = 1
if one % 2 = = 0 :
min2 + = one / / 2
else :
min2 + = (one / / 2 ) + 2
print ( min (min1, min2))
N = 4
X = 2
S = "1100"
min_operations(N, X, S)
|
C#
using System;
class GFG
{
static void MinOperations( int N, int X, char [] S)
{
int min1 = 0;
bool [] vis = new bool [N];
for ( int i = 0; i < N; i++)
{
if (!vis[i])
{
int one = 0;
int zero = 0;
for ( int j = i; j < N; j += X)
{
vis[j] = true ;
if (S[j] == '0' )
zero++;
else
one++;
}
if (one == 0)
{
min1 = int .MaxValue;
break ;
}
else
min1 += zero;
}
}
vis = new bool [N];
int min2 = 0;
for ( int i = 0; i < N; i++)
{
if (!vis[i])
{
int one = 0;
for ( int j = i; j < N; j += X)
{
vis[j] = true ;
if (S[j] == '1' )
one++;
}
if (one % 2 == 0)
min2 += one / 2;
else
min2 += (one / 2) + 2;
}
}
Console.WriteLine(Math.Min(min1, min2));
}
static void Main()
{
int N = 4;
int X = 2;
char [] S = { '1' , '1' , '0' , '0' };
MinOperations(N, X, S);
}
}
|
Javascript
function minOperations(N, X, S) {
let min1 = 0;
let vis = new Array(N).fill( false );
for (let i = 0; i < N; i++) {
if (!vis[i]) {
let one = 0;
let zero = 0;
for (let j = i; j < N; j += X) {
vis[j] = true ;
if (S[j] === '0' ) {
zero++;
} else {
one++;
}
}
if (one === 0) {
min1 = Infinity;
break ;
} else {
min1 += zero;
}
}
}
vis = new Array(N).fill( false );
let min2 = 0;
for (let i = 0; i < N; i++) {
if (!vis[i]) {
let one = 0;
for (let j = i; j < N; j += X) {
vis[j] = true ;
if (S[j] === '1' ) {
one++;
}
}
if (one % 2 === 0) {
min2 += one / 2;
} else {
min2 += (one / 2) + 2;
}
}
}
console.log(Math.min(min1, min2));
}
const N = 4;
const X = 2;
const S = [ '1' , '1' , '0' , '0' ];
minOperations(N, X, S);
|
Time Complexity: O(N2)
Auxiliary Space: O(N), As boolean Array of length N is used.
Share your thoughts in the comments
Please Login to comment...