Minimize flips to make substrings of size K same and alternative
Last Updated :
06 May, 2022
Given a binary string S of length N, the task is to minimize the count of operations required to find a binary string T of the same length N such that:
- In one operation, it is allowed to flip any bit, i.e. convert 0 to 1 or vice versa.
- In the binary string T, choose a number K, such that:
- N is perfectly divisible by K, and
- The first K bits in T are 0, the next K are 1, the next K are 0, and so on.
Examples:
Input: S = 1011011
Output: 4
Explanation:
If we choose K = 1, then required string S=0101010, Moves required 4
If we choose K = 7, then required string S=0000000, Moves required 5
Values of K= 2, 3, 4, 5, 6 is not allowed because, it is not perfectly divide N = 7.
Choose K = 1. So, Final String is 0101010, Flip the first, second, third and seventh bit. Print 4 because string S satisfies all conditions after performing 4 moves.
Input: S = 000001
Output: 1
Explanation:
If we choose K=1, then required string S=010101, Moves required 2
If we choose K=2, then required string S=001100, Moves required 3
If we choose K=3, then required string S=000111, Moves required 2
If we choose K=6, then required string S=000000, Moves required 1
So, Select K=6, So, output will be1.
Approach: The approach is based on the following observation:
It is mentioned in the problem statement itself that we have to choose K such that N is divisible by K, so we can break our problem into subproblem to find all the divisors of N and then find number of operations required for each of the divisor and choose the minimum number of operation between all of them.
Based on the above observation, follow the steps below to implement this approach:
- Find all the divisor of N (size of given string).
- For each divisor, Traverse the String and for each iteration:
- Count the number of changes required in given string if we choose the K = current divisor.
- If current changes required is less than the previous result then update it with the current result.
- Return the minimum changes required.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
void findAllDivisors( int n, vector< int >& v)
{
for ( int i = 1; i <= sqrt (n); i++) {
if (n % i == 0) {
if (n / i == i)
v.push_back(i);
else {
v.push_back(n / i);
}
}
}
}
int findMinOperations(string& S)
{
int n = S.length(), result = n;
vector< int > v;
findAllDivisors(n, v);
for ( int i = 0; i < v.size(); i++) {
int count = 0;
bool flag = false ;
for ( int j = 0; j < n; j += v[i]) {
for ( int k = j; k < j + v[i] && k < n; k++) {
if (flag && S[k] == '0' )
count++;
if (!flag && S[k] == '1' )
count++;
}
flag = (flag == false );
}
if (count < result)
result = count;
}
return result;
}
int main()
{
string S = "101101" ;
cout << findMinOperations(S);
return 0;
}
|
Java
import java.util.*;
class GFG {
static void findAllDivisors( int n, Vector<Integer> v)
{
for ( int i = 1 ; i <= Math.sqrt(n); i++) {
if (n % i == 0 ) {
if (n / i == i)
v.add(i);
else {
v.add(n / i);
}
}
}
}
static int findMinOperations(String S)
{
int n = S.length();
int result = n;
Vector<Integer> v = new Vector<Integer>();
findAllDivisors(n, v);
for ( int i = 0 ; i < v.size(); i++) {
int count = 0 ;
boolean flag = false ;
for ( int j = 0 ; j < n; j += v.get(i)) {
for ( int k = j; k < j + v.get(i) && k < n;
k++) {
if (flag && S.charAt(k) == '0' )
count++;
if (!flag && S.charAt(k) == '1' )
count++;
}
flag = (flag == false );
}
if (count < result)
result = count;
}
return result;
}
public static void main(String[] args)
{
String S = "101101" ;
System.out.print(findMinOperations(S));
}
}
|
Python3
def findAllDivisors(n, v):
for i in range ( 1 , 1 + int (n * * 0.5 )):
if n % i = = 0 :
if (n / / i) = = i:
v.append(i)
else :
v.append(n / / i)
return v
def findMinOperations(S):
n = len (S)
result = n
v = []
v = findAllDivisors(n, v)
for i in range ( len (v)):
count = 0
flag = False
for j in range ( 0 , n, v[i]):
for k in range (j, min (j + v[i], n), 1 ):
if (flag and S[k]) = = "0" :
count + = 1
if ( not flag and S[k]) = = "1" :
count + = 1
flag = bool (flag = = False )
if count < result:
result = count
return result
S = "101101"
print (findMinOperations(S))
|
C#
using System;
using System.Collections;
public class GFG{
static void findAllDivisors( int n, ArrayList v)
{
for ( int i = 1; i <= Math.Sqrt(n); i++) {
if (n % i == 0) {
if (n / i == i)
v.Add(i);
else {
v.Add(n / i);
}
}
}
}
static int findMinOperations(String S)
{
int n = S.Length;
int result = n;
ArrayList v = new ArrayList();
findAllDivisors(n, v);
for ( int i = 0; i < v.Count; i++) {
int count = 0;
bool flag = false ;
for ( int j = 0; j < n; j += ( int )v[i]) {
for ( int k = j; k < j + ( int )v[i] && k < n;
k++) {
if (flag && S[k] == '0' )
count++;
if (!flag && S[k] == '1' )
count++;
}
flag = (flag == false );
}
if (count < result)
result = count;
}
return result;
}
static public void Main (){
string S = "101101" ;
Console.Write(findMinOperations(S));
}
}
|
Javascript
function findAllDivisors(n, v)
{
for ( var i = 1; i <= Math.floor(Math.sqrt(n)); i++) {
if (n % i == 0) {
if (Math.floor(n / i) == i)
v.push(i);
else {
v.push(Math.floor(n / i));
}
}
}
return v;
}
function findMinOperations(S)
{
var n = S.length;
var result = n;
var v = [];
v = findAllDivisors(n, v);
for ( var i = 0; i < v.length; i++) {
var count = 0;
var flag = false ;
for ( var j = 0; j < n; j += v[i]) {
for ( var k = j; k < j + v[i] && k < n; k++) {
if (flag && S[k] == '0' )
count++;
if (!flag && S[k] == '1' )
count++;
}
flag = (flag == false );
}
if (count < result)
result = count;
}
return result;
}
var S = "101101" ;
document.write(findMinOperations(S));
|
Time Complexity: O(N*sqrt(N)), O(sqrt(N)) to find all divisors and O(N) to find all operations for each divisor.
Auxiliary Space: O(sqrt(N)), for storing all divisors.
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...