给定一个大小为N的二进制数组arr[]和一个正整数K ,任务是找到给定数组arr[]中大小为K 的任何子数组需要翻转的最小次数,以使所有数组元素等于1 .如果无法这样做,则打印“-1” 。
例子:
Input: arr[] = {0, 1, 0}, K = 1
Output: 2
Explanation:
Perform the operation in the following order:
Operation 1: Flip all elements present in the subarray {arr[0]}. Now, the array modifies to {1, 1, 0}.
Operation 2: Flip all elements present in the subarray {arr[2]}. Now the array modifies to {1, 1, 1}.
Therefore, the total number of operations required is 2.
Input: arr[] = {1, 1, 0}, K = 2
Output: -1
处理方法:按照以下步骤解决问题:
- 初始化一个辅助数组,比如大小为N 的isFlipped[] 。
- 初始化一个变量,比如ans,以存储所需的K长度子数组翻转的最小数量。
- 使用变量i遍历给定数组arr[]并执行以下步骤:
- 如果i的值大于0 ,则将isFlipped[i]的值更新为(isFlipped[i] + isFlipped[i – 1])%2 。
- 检查当前元素是否需要翻转,即如果A[i]的值为0且isFlipped[i]未设置或, A[i]的值为1且isFlipped[i]已设置,则执行以下步骤:
- 如果这样的 K 长度子数组是不可能的,则打印“-1”并跳出循环,因为不可能使所有数组元素都等于1 。
- 将ans和isFlipped[i]增加1 ,并将isFlipped[i + K]减少1 。
- 否则,继续下一次迭代。
- 完成上述步骤后,如果可以使所有数组元素都为1 ,则打印ans的值作为结果。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find the minimum number
// K-length subarrays required to be
// flipped to make all array elements 1
void minimumOperations(vector& A, int K)
{
// Stores whether an element
// can be flipped or not
vector isflipped(A.size(), 0);
// Store the required number of flips
int ans = 0;
// Traverse the array, A[]
for (int i = 0; i < A.size(); i++) {
// Find the prefix sum
// for the indices i > 0
if (i > 0) {
isflipped[i] += isflipped[i - 1];
isflipped[i] %= 2;
}
// Check if the current element
// is required to be flipped
if (A[i] == 0 && !isflipped[i]) {
// If subarray of size K
// is not possible, then
// print -1 and return
if ((A.size() - i + 1) <= K) {
cout << -1;
return;
}
// Increment ans by 1
ans++;
// Change the current
// state of the element
isflipped[i]++;
// Decrement isFlipped[i + K]
isflipped[i + K]--;
}
else if (A[i] == 1 && isflipped[i]) {
// If subarray of size K
// is not possible, then
// print -1 and return
if ((A.size() - i + 1) <= K) {
cout << -1;
return;
}
// Increment ans by 1
ans++;
// Change the current
// state of the element
isflipped[i]++;
// Decrement isFlipped[i+K]
isflipped[i + K]--;
}
}
// Print the result
cout << ans;
}
// Driver Code
int main()
{
vector arr = { 0, 1, 0 };
int K = 1;
minimumOperations(arr, K);
return 0;
}
Java
// Java program for the above approach
class GFG
{
// Function to find the minimum number
// K-length subarrays required to be
// flipped to make all array elements 1
static void minimumOperations(int[] A, int K)
{
// Stores whether an element
// can be flipped or not
int[] isflipped = new int[A.length+1];
// Store the required number of flips
int ans = 0;
// Traverse the array, A[]
for (int i = 0; i < A.length; i++)
{
// Find the prefix sum
// for the indices i > 0
if (i > 0) {
isflipped[i] += isflipped[i - 1];
isflipped[i] %= 2;
}
// Check if the current element
// is required to be flipped
if (A[i] == 0 && isflipped[i] == 0)
{
// If subarray of size K
// is not possible, then
// print -1 and return
if ((A.length - i + 1) <= K)
{
System.out.println(-1);
return;
}
// Increment ans by 1
ans++;
// Change the current
// state of the element
isflipped[i]++;
// Decrement isFlipped[i + K]
isflipped[i + K]--;
} else if (A[i] == 1 && isflipped[i] != 0)
{
// If subarray of size K
// is not possible, then
// print -1 and return
if ((A.length - i + 1) <= K)
{
System.out.println(-1);
return;
}
// Increment ans by 1
ans++;
// Change the current
// state of the element
isflipped[i]++;
// Decrement isFlipped[i+K]
isflipped[i + K]--;
}
}
// Print the result
System.out.println(ans);
}
// Driver Code
public static void main(String[] args)
{
int[] arr = {0, 1, 0};
int K = 1;
minimumOperations(arr, K);
}
}
// This code is contributed by user_qa7r.
Python3
# Python3 program for the above approach
# Function to find the minimum number
# K-length subarrays required to be
# flipped to make all array elements 1
def minimumOperations(A, K):
# Stores whether an element
# can be flipped or not
isflipped = [0] * (len(A) + 1)
# Store the required number of flips
ans = 0
# Traverse the array, A[]
for i in range(len(A)):
# Find the prefix sum
# for the indices i > 0
if (i > 0):
isflipped[i] += isflipped[i - 1]
isflipped[i] %= 2
# Check if the current element
# is required to be flipped
if (A[i] == 0 and not isflipped[i]):
# If subarray of size K
# is not possible, then
# print -1 and return
if ((len(A) - i + 1) <= K):
print(-1)
return
# Increment ans by 1
ans += 1
# Change the current
# state of the element
isflipped[i] += 1
# Decrement isFlipped[i + K]
isflipped[i + K] -= 1
elif (A[i] == 1 and isflipped[i]):
# If subarray of size K
# is not possible, then
# print -1 and return
if ((len(A) - i + 1) <= K):
print(-1)
return
# Increment ans by 1
ans += 1
# Change the current
# state of the element
isflipped[i] += 1
# Decrement isFlipped[i+K]
isflipped[i + K] -= 1
# Print the result
print(ans)
# Driver Code
if __name__ == "__main__":
arr = [0, 1, 0]
K = 1
minimumOperations(arr, K)
# This code is contributed by ukasp
C#
// C# program for the above approach
using System;
using System.Collections.Generic;
class GFG{
// Function to find the minimum number
// K-length subarrays required to be
// flipped to make all array elements 1
static void minimumOperations(List A, int K)
{
// Stores whether an element
// can be flipped or not
List isflipped = new List();
for(int i = 0; i < A.Count + 1; i++)
isflipped.Add(0);
// Store the required number of flips
int ans = 0;
// Traverse the array, A[]
for(int i = 0; i < A.Count; i++)
{
// Find the prefix sum
// for the indices i > 0
if (i > 0)
{
isflipped[i] += isflipped[i - 1];
isflipped[i] %= 2;
}
// Check if the current element
// is required to be flipped
if (A[i] == 0 && isflipped[i] == 0)
{
// If subarray of size K
// is not possible, then
// print -1 and return
if ((A.Count - i + 1) <= K)
{
Console.Write(-1);
return;
}
// Increment ans by 1
ans += 1;
// Change the current
// state of the element
isflipped[i] += 1;
// Decrement isFlipped[i + K]
isflipped[i + K] -= 1;
}
else if (A[i] == 1 && isflipped[i] != 0)
{
// If subarray of size K
// is not possible, then
// print -1 and return
if ((A.Count - i + 1) <= K)
{
Console.Write(-1);
return;
}
// Increment ans by 1
ans += 1;
// Change the current
// state of the element
isflipped[i] += 1;
// Decrement isFlipped[i+K]
isflipped[i + K] -= 1;
}
}
// Print the result
Console.WriteLine(ans);
}
// Driver Code
public static void Main()
{
List arr = new List(){ 0, 1, 0 };
int K = 1;
minimumOperations(arr, K);
}
}
// This code is contributed by bgangwar59
Javascript
Java
/*package whatever //do not write package name here */
import java.io.*;
import java.util.*;
class GFG {
static int minKBitFlips(int[] A, int K)
{
// store previous flip events
Queue flip = new LinkedList<>();
int count = 0;
for (int i = 0; i < A.length; i++) {
// remove an item which is out range of window.
if (!flip.isEmpty() && (i - flip.peek() >= K)) {
flip.poll();
}
/*
In a window, if A[i] is a even number with
even times fliped, it need to be fliped again.
On other hand,if A[i] is a odd number with odd
times fliped, it need to be fliped again.
*/
if (A[i] % 2 == flip.size() % 2) {
if (i + K - 1 >= A.length) {
return -1;
}
flip.offer(i); // insert
count++;
}
}
return count;
}
public static void main(String[] args)
{
int[] A = { 0, 1, 0 };
int K = 1;
int ans = minKBitFlips(A, K);
System.out.println(ans);
}
}
Java
/*package whatever //do not write package name here */
import java.io.*;
import java.util.*;
class GFG {
static int minKBitFlips(int[] A, int K)
{
int[] temp = new int[A.length];
int count = 0;
int flip = 0;
for (int i = 0; i < A.length; ++i) {
flip ^= temp[i];
if (A[i] == flip) { // If we must flip the
// subarray starting here...
count++; // We're flipping the subarray from
// A[i] to A[i+K-1]
if (i + K > A.length) {
return -1; // If we can't flip the
// entire subarray, its
// impossible
}
flip ^= 1;
if (i + K < A.length) {
temp[i + K] ^= 1;
}
}
}
return count;
}
public static void main(String[] args)
{
int[] A = { 0, 1, 0 };
int K = 1;
int ans = minKBitFlips(A, K);
System.out.println(ans);
}
}
2
时间复杂度: O(N)
辅助空间: O(N)
方法 2:- 滑动窗口
Java
/*package whatever //do not write package name here */
import java.io.*;
import java.util.*;
class GFG {
static int minKBitFlips(int[] A, int K)
{
// store previous flip events
Queue flip = new LinkedList<>();
int count = 0;
for (int i = 0; i < A.length; i++) {
// remove an item which is out range of window.
if (!flip.isEmpty() && (i - flip.peek() >= K)) {
flip.poll();
}
/*
In a window, if A[i] is a even number with
even times fliped, it need to be fliped again.
On other hand,if A[i] is a odd number with odd
times fliped, it need to be fliped again.
*/
if (A[i] % 2 == flip.size() % 2) {
if (i + K - 1 >= A.length) {
return -1;
}
flip.offer(i); // insert
count++;
}
}
return count;
}
public static void main(String[] args)
{
int[] A = { 0, 1, 0 };
int K = 1;
int ans = minKBitFlips(A, K);
System.out.println(ans);
}
}
2
复杂性分析:-
时间复杂度: O(N),其中 N 是数组的长度。
空间复杂度: O(N)。
方法3:-贪婪
Java
/*package whatever //do not write package name here */
import java.io.*;
import java.util.*;
class GFG {
static int minKBitFlips(int[] A, int K)
{
int[] temp = new int[A.length];
int count = 0;
int flip = 0;
for (int i = 0; i < A.length; ++i) {
flip ^= temp[i];
if (A[i] == flip) { // If we must flip the
// subarray starting here...
count++; // We're flipping the subarray from
// A[i] to A[i+K-1]
if (i + K > A.length) {
return -1; // If we can't flip the
// entire subarray, its
// impossible
}
flip ^= 1;
if (i + K < A.length) {
temp[i + K] ^= 1;
}
}
}
return count;
}
public static void main(String[] args)
{
int[] A = { 0, 1, 0 };
int K = 1;
int ans = minKBitFlips(A, K);
System.out.println(ans);
}
}
2
复杂性分析:-
时间复杂度: O(N),其中 N 是数组的长度。
空间复杂度: O(N)。
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live