最多改变 k 个 '0' 形成 '1' 的最长子段 |设置 2(使用队列)
给定一个二进制数组a[]和一个数字k ,我们需要通过最多改变 k个'0's来找到'1's的最长子段的长度。
例子:
Input: a[] = {1, 0, 0, 1, 1, 0, 1}, k = 1
Output: 4
Explanation: Here, we should only change 1 zero(0). Maximum possible length we can get is by changing the 3rd zero in the array, we get a[] = {1, 0, 0, 1, 1, 1, 1}
Input: a[] = {1, 0, 0, 1, 0, 1, 0, 1, 0, 1}, k = 2
Output: 5
Two Pointer Approach:参考本文的 Set 1,了解如何实现双指针方法。
队列方法:任务可以在队列的帮助下解决。将到目前为止遇到的0的索引存储在queue中。对于每个0 ,检查K的值是否大于 0 ,如果是非零,将其翻转为1 ,并相应地最大化子段长度,否则左移指针(最初在字符串的开始索引处) 到第一个零(队列的前面)+ 1的索引。
请按照以下步骤解决问题:
- 声明一个队列来存储0s已访问的索引。
- 遍历字符串,如果当前字符为0并且留下一些拼写,即(k != 0) ,则使用拼写 ie (递减 k)。此外,存储发生“0”的索引。
- 如果k = 0 ,则取出队列的最前面并存储在一个变量中。
- 将长度存储为i-low和上一个答案之间的最大值。
- 低移到第一个“0”+1的索引并增加k。
- 最后,返回答案。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to Find longest subsegment of 1s
int get(int n, int k, int arr[])
{
// Queue for storing indices of 0s
queue q;
int low = 0;
int ans = INT_MIN;
int p = k;
int i = 0;
while (i < n) {
// If the current character is 1
// then increment i by 1
if (arr[i] == 1) {
i++;
}
// If the current character is 0
// and some spells are
// left then use them
else if (arr[i] == 0 && k != 0) {
q.push(i);
k--;
i++;
}
// If k == 0
else {
// Take out the index where
// the first "0" was found
int x = q.front();
q.pop();
// Store the length as max
// between i-low and that
// of the previous answer
ans = max(ans, i - low);
// Shift low to index
// of first "O" + 1
low = x + 1;
// Increase spell by 1
k++;
}
// Store the length between
// the i-low and that of
// previous answer
ans = max(ans, i - low);
}
return ans;
}
// Driver Code
int main()
{
int N = 10;
int K = 2;
int arr[] = { 1, 0, 0, 1, 0,
1, 0, 1, 0, 1 };
cout << get(N, K, arr) << endl;
return 0;
}
Java
// Java program for the above approach
import java.util.LinkedList;
import java.util.Queue;
class GFG{
// Function to Find longest subsegment of 1s
static int get(int n, int k, int arr[])
{
// Queue for storing indices of 0s
Queue q = new LinkedList();
int low = 0;
int ans = Integer.MIN_VALUE;
int i = 0;
while (i < n)
{
// If the current character is 1
// then increment i by 1
if (arr[i] == 1)
{
i++;
}
// If the current character is 0
// and some spells are
// left then use them
else if (arr[i] == 0 && k != 0)
{
q.add(i);
k--;
i++;
}
// If k == 0
else
{
// Take out the index where
// the first "0" was found
int x = q.peek();
q.remove();
// Store the length as max
// between i-low and that
// of the previous answer
ans = Math.max(ans, i - low);
// Shift low to index
// of first "O" + 1
low = x + 1;
// Increase spell by 1
k++;
}
// Store the length between
// the i-low and that of
// previous answer
ans = Math.max(ans, i - low);
}
return ans;
}
// Driver Code
public static void main(String args[])
{
int N = 10;
int K = 2;
int arr[] = { 1, 0, 0, 1, 0,
1, 0, 1, 0, 1 };
System.out.println(get(N, K, arr));
}
}
// This code is contributed by gfking
Python3
# Python code for the above approach
# Function to Find longest subsegment of 1s
def get(n, k, arr):
# Queue for storing indices of 0s
q = []
low = 0
ans = 10 ** -9
p = k
i = 0
while (i < n):
# If the current character is 1
# then increment i by 1
if (arr[i] == 1):
i += 1
# If the current character is 0
# and some spells are
# left then use them
elif (arr[i] == 0 and k != 0):
q.append(i)
k -= 1
i += 1
# If k == 0
else:
# Take out the index where
# the first "0" was found
x = q[0]
q.pop(0)
# Store the length as max
# between i-low and that
# of the previous answer
ans = max(ans, i - low)
# Shift low to index
# of first "O" + 1
low = x + 1
# Increase spell by 1
k += 1
# Store the length between
# the i-low and that of
# previous answer
ans = max(ans, i - low)
return ans
# Driver Code
N = 10
K = 2
arr = [1, 0, 0, 1, 0, 1, 0, 1, 0, 1]
print(get(N, K, arr))
# This code is contributed by Saurabh Jaiswal
C#
// C# program for the above approach
using System;
using System.Collections.Generic;
class GFG {
// Function to Find longest subsegment of 1s
static int get(int n, int k, int[] arr)
{
// Queue for storing indices of 0s
Queue q = new Queue();
int low = 0;
int ans = Int32.MinValue;
int i = 0;
while (i < n) {
// If the current character is 1
// then increment i by 1
if (arr[i] == 1) {
i++;
}
// If the current character is 0
// and some spells are
// left then use them
else if (arr[i] == 0 && k != 0) {
q.Enqueue(i);
k--;
i++;
}
// If k == 0
else {
// Take out the index where
// the first "0" was found
int x = q.Peek();
q.Dequeue();
// Store the length as max
// between i-low and that
// of the previous answer
ans = Math.Max(ans, i - low);
// Shift low to index
// of first "O" + 1
low = x + 1;
// Increase spell by 1
k++;
}
// Store the length between
// the i-low and that of
// previous answer
ans = Math.Max(ans, i - low);
}
return ans;
}
// Driver Code
public static void Main()
{
int N = 10;
int K = 2;
int[] arr = { 1, 0, 0, 1, 0, 1, 0, 1, 0, 1 };
Console.WriteLine(get(N, K, arr));
}
}
// This code is contributed by ukasp.
Javascript
输出
5
时间复杂度: O(N)
辅助空间: O(k)