给定一个二进制字符串S和一个整数K ,任务是找到所需的最小翻转次数,以使每个长度为K的子字符串至少包含一个“ 1” 。
例子:
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
天真的方法:
为了解决该问题,最简单的方法是对长度为K的每个子串进行迭代,并找到满足给定条件所需的最小翻转次数。
时间复杂度: O(N * K)
高效方法:
这个想法是使用滑动窗口方法。
- 将窗口大小设置为K。
- 存储先前出现的索引1。
- 如果当前位未设置并且当前第i位与先前设置的位之间的差超过K ,则设置当前位并将当前索引存储为先前设置的位,然后继续进行操作。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
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;
}
Java
// 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
Python3
# 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))
C#
// 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
Javascript
输出:
3
时间复杂度: O(N + K)
辅助空间: O(1)