Minimum bit flips such that every K consecutive bits contain at least one set bit

Given a binary string S, and an integer K, the task is to find the minimum number of flips required such that every substring of length K contains at least one ‘1’.

Examples:

Input: S = “10000001” K = 2
Output: 3
Explanation:
We need only 3 changes in string S ( at position 2, 4 and 6 ) so that the string contain at least one ‘1’ in every sub-string of length 2.

Input: S = “000000” K = 3
Output: 2
Explanation:
We need only 3 changes in string S ( at position 2 and 5 ) so that the string contain at least one ‘1’ in every sub-string of length 3.

Input: S = “111010111” K = 2
Output: 0



Naive Approach:
To solve the problem, the simplest approach is to iterate for each substring of length K and find the minimum number of flips required to satisfy the given condition.
Time complexity: O(N * K)

Efficient Approach:
The idea is to use Sliding Window Approach.

  • Set a window size of K.
  • Store the index of previous appearance of 1.
  • If the current bit is unset and the difference between the current ith bit and the previous set bit exceeds K, set the current bit and store the current index as that of the previous set bit and proceed further.

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
  
// Function to count min flips
int CountMinFlips(string s, int n,
                  int k)
{
  
    // To store the count of minimum
    // flip required
    int cnt = 0;
  
    // To store the position of last '1'
    int prev = -1;
  
    for (int i = 0; i < k; i++) {
  
        // Track last position of '1'
        // in current window of size k
        if (s[i] == '1') {
            prev = i;
        }
    }
  
    // If no '1' is present in the current
    // window of size K
    if (prev == -1) {
        cnt++;
  
        // Set last index of window '1'
        s[k - 1] = '1';
  
        // Track previous '1'
        prev = k - 1;
    }
  
    // Traverse the given string
    for (int i = k; i < n; i++) {
  
        // If the current bit is not set,
        // then the condition for fliping
        // the current bit
        if (s[i] != '1') {
            if (prev <= (i - k)) {
  
                // Set i'th index to '1'
                s[i] = '1';
  
                // Track previous one
                prev = i;
  
                // Increment count
                cnt++;
            }
        }
  
        // Else update the prev set bit
        // position to current position
        else {
            prev = i;
        }
    }
  
    // Return the final count
    return (cnt);
}
  
// Driver Code
int main()
{
    // Given binary string
    string str = "10000001";
  
    // Size of given string str
    int n = str.size();
  
    // Window size
    int k = 2;
  
    // Function Call
    cout << CountMinFlips(str, n, k)
         << endl;
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program for the above approach
import java.util.*;
  
class GFG{
  
// Function to count min flips
static int CountMinFlips(char []s, int n,
                                   int k)
{
      
    // To store the count of minimum
    // flip required
    int cnt = 0;
  
    // To store the position of last '1'
    int prev = -1;
  
    for(int i = 0; i < k; i++) 
    {
         
       // Track last position of '1'
       // in current window of size k
       if (s[i] == '1')
       {
           prev = i;
       }
    }
  
    // If no '1' is present in the current
    // window of size K
    if (prev == -1)
    {
        cnt++;
  
        // Set last index of window '1'
        s[k - 1] = '1';
  
        // Track previous '1'
        prev = k - 1;
    }
  
    // Traverse the given String
    for(int i = k; i < n; i++)
    {
         
       // If the current bit is not set,
       // then the condition for fliping
       // the current bit
       if (s[i] != '1')
       {
           if (prev <= (i - k))
           {
                 
               // Set i'th index to '1'
               s[i] = '1';
                 
               // Track previous one
               prev = i;
                 
               // Increment count
               cnt++;
           }
       }
         
       // Else update the prev set bit
       // position to current position
       else
       {
           prev = i;
       }
    }
      
    // Return the final count
    return (cnt);
}
  
// Driver Code
public static void main(String[] args)
{
  
    // Given binary String
    String str = "10000001";
  
    // Size of given String str
    int n = str.length();
  
    // Window size
    int k = 2;
  
    // Function Call
    System.out.print(CountMinFlips(
                     str.toCharArray(), n, k) + "\n");
}
}
  
// This code is contributed by Rohit_ranjan

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 code to count minimum no.
# of flips required such that 
# every substring of length K
# contain at least one '1'.
  
# Function to count min flips
def CountMinFlips(s, n, k):
    cnt = 0
    prev = -1
    for i in range(0, k):
        # Track last position of '1'
        # in current window of size k
        if(s[i]=='1'):
            prev = i;
              
    # means no '1' is present
    if(prev == -1): 
        cnt += 1
        # track previous '1'
        prev = k-1
          
      
    for i in range(k, n):
        if(s[i] != '1'):
            if( prev <= (i-k) ):
                  
                # track previous one
                prev = i;
                  
                # increment count
                cnt += 1 
        else:
            prev = i
      
    return(cnt);
  
# Driver code
s = "10000001"
n = len(s)
k = 2
print(CountMinFlips(s, n, k))

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program for the above approach
using System;
class GFG{
  
// Function to count min flips
static int CountMinFlips(char []s, int n,
                                   int k)
{
      
    // To store the count of minimum
    // flip required
    int cnt = 0;
  
    // To store the position of last '1'
    int prev = -1;
  
    for(int i = 0; i < k; i++) 
    {
          
        // Track last position of '1'
        // in current window of size k
        if (s[i] == '1')
        {
            prev = i;
        }
    }
  
    // If no '1' is present in the current
    // window of size K
    if (prev == -1)
    {
        cnt++;
  
        // Set last index of window '1'
        s[k - 1] = '1';
  
        // Track previous '1'
        prev = k - 1;
    }
  
    // Traverse the given String
    for(int i = k; i < n; i++)
    {
          
        // If the current bit is not set,
        // then the condition for fliping
        // the current bit
        if (s[i] != '1')
        {
            if (prev <= (i - k))
            {
                      
                // Set i'th index to '1'
                s[i] = '1';
                      
                // Track previous one
                prev = i;
                      
                // Increment count
                cnt++;
            }
        }
              
        // Else update the prev set bit
        // position to current position
        else
        {
            prev = i;
        }
    }
      
    // Return the readonly count
    return (cnt);
}
  
// Driver Code
public static void Main(String[] args)
{
  
    // Given binary String
    String str = "10000001";
  
    // Size of given String str
    int n = str.Length;
  
    // Window size
    int k = 2;
  
    // Function Call
    Console.Write(CountMinFlips(
                  str.ToCharArray(), n, k) + "\n");
}
}
  
// This code is contributed by sapnasingh4991

chevron_right


Output:

3

Time complexity: O(N + K)
Auxiliary Space: O(1)

competitive-programming-img




My Personal Notes arrow_drop_up

Recommended Posts:


Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.