Open In App

Minimum operations to convert given string into all 1s or 0s

Last Updated : 30 Nov, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

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)
          • zero++
        • Else
          • one++
      • If (one == 0)
        • min1 = INT_MAX
        • break the loop
      • Else
        • min1 += zero
  • 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)
            • one++
        • If (one % 2 == 0)
          • min2 += one / 2
        • Else
          • min2 += (one / 2) + 2
  • Output min(min1, min2)

Implementation of the above approach:

C++




#include <bits/stdc++.h>
using namespace std;
 
using namespace std;
 
// Method to output the minimum number of operations
void Min_Operations(int N, int X, char S[]) {
    // Approach for all ones
    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;
        }
    }
 
    // Approach for all zeros
    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() {
    // Inputs
    int N = 4;
    int X = 2;
    char S[] = "1100";
 
    // Function call
    Min_Operations(N, X, S);
 
    return 0;
}


Java




// Java code to implement the approach
 
import java.io.*;
import java.util.*;
 
// Driver Class
class GFG {
 
    // Driver Function
    public static void main(String[] args)
    {
 
        // Inputs
        int N = 4;
        int X = 2;
        char[] S = ("1100").toCharArray();
 
        // Function call
        Min_Operations(N, X, S);
    }
 
    // Method to output the minimum number
    // of operations
    public static void Min_Operations(int N, int X,
                                      char[] S)
    {
        // Approach for all ones
        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;
            }
        }
 
        // Approach for all zeros
        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




# Method to output the minimum number of operations
def min_operations(N, X, S):
    # Approach for all ones
    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
 
    # Approach for all zeros
    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))
 
# Inputs
N = 4
X = 2
S = "1100"
 
# Function call
min_operations(N, X, S)
 
# This code is contributed by shivamgupta0987654321


C#




//code by flutterfly
using System;
 
class GFG
{
    // Method to output the minimum number of operations
    static void MinOperations(int N, int X, char[] S)
    {
        // Approach for all ones
        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;
            }
        }
 
        // Approach for all zeros
        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()
    {
        // Inputs
        int N = 4;
        int X = 2;
        char[] S = { '1', '1', '0', '0' };
 
        // Function call
        MinOperations(N, X, S);
    }
}


Javascript




// Method to output the minimum number of operations
function minOperations(N, X, S) {
    // Approach for all ones
    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;
            }
        }
    }
 
    // Approach for all zeros
    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));
}
 
// Inputs
const N = 4;
const X = 2;
const S = ['1', '1', '0', '0'];
 
// Function call
minOperations(N, X, S);


Output

2






Time Complexity: O(N2)
Auxiliary Space: O(N), As boolean Array of length N is used.



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads