📌  相关文章
📜  使所有数组元素等于 1 所需的 K 长度子数组的翻转最小化

📅  最后修改于: 2021-10-26 05:18:16             🧑  作者: Mango

给定一个大小为N的二进制数组arr[]和一个正整数K ,任务是找到给定数组arr[]中大小为K 的任何子数组需要翻转的最小次数,以使所有数组元素等于1 .如果无法这样做,则打印“-1”

例子:

处理方法:按照以下步骤解决问题:

  • 初始化一个辅助数组,比如大小为N 的isFlipped[]
  • 初始化一个变量,比如ans,以存储所需的K长度子数组翻转的最小数量。
  • 使用变量i遍历给定数组arr[]并执行以下步骤:
    • 如果i的值大于0 ,则将isFlipped[i]的值更新为(isFlipped[i] + isFlipped[i – 1])%2
    • 检查当前元素是否需要翻转,即如果A[i]的值为0isFlipped[i]未设置或, A[i]的值为1isFlipped[i]已设置,则执行以下步骤:
      • 如果这样的 K 长度子数组是不可能的,则打印“-1”并跳出循环,因为不可能使所有数组元素都等于1
      • ansisFlipped[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


C++
#include 
using namespace std;
 
int minKBitFlips(int A[], int K, int N)
{
   
    // store previous flip events
    queue flip;
    int count = 0;
    for (int i = 0; i < N; i++)
    {
       
        // remove an item which is out range of window.
        if (flip.size() > 0 && (i - flip.front() >= K)) {
            flip.pop();
        }
       
        /*
         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 >= N) {
                return -1;
            }
            flip.push(i); // insert
            count++;
        }
    }
    return count;
}
     
int main()
{
    int A[] = { 0, 1, 0 };
    int N = sizeof(A) / sizeof(A[0]);
    int K = 1;
    int ans = minKBitFlips(A, K, 3);
    cout << ans;
 
    return 0;
}
 
// This code is contributed by divyeshrabadiya07.


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);
    }
}


Python3
def minKBitFlips(A, K, N):
     
    # Store previous flip events
    flip = []
    count = 0
     
    for i in range(N):
         
        # Remove an item which is out range of window.
        if (len(flip) > 0 and (i - flip[0] >= K)):
            flip.pop(0)
     
        """
        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 == len(flip) % 2):
            if (i + K - 1 >= N):
                return -1
                 
            # Insert
            flip.append(i)
            count += 1
             
    return count
 
# Driver code
A = [ 0, 1, 0 ]
N = len(A)
K = 1
 
ans = minKBitFlips(A, K, 3)
 
print(ans)
 
# This code is contributed by rameshtravel07


C#
using System;
using System.Collections;
class GFG {
     
    static int minKBitFlips(int[] A, int K)
    {
       
        // store previous flip events
        Queue flip = new Queue();
        int count = 0;
        for (int i = 0; i < A.Length; i++)
        {
           
            // remove an item which is out range of window.
            if (flip.Count > 0 && (i - (int)flip.Peek() >= K)) {
                flip.Dequeue();
            }
           
            /*
             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.Count % 2) {
                if (i + K - 1 >= A.Length) {
                    return -1;
                }
                flip.Enqueue(i); // insert
                count++;
            }
        }
        return count;
    }
     
  static void Main() {
    int[] A = { 0, 1, 0 };
    int K = 1;
    int ans = minKBitFlips(A, K);
    Console.WriteLine(ans);
  }
}
 
// This code is contributed by mukesh07.


Javascript


C++
#include 
using namespace std;
 
int minKBitFlips(int A[], int K, int N)
{
    int temp[N];
    memset(temp, 0, N);
    int count = 0;
    int flip = 0;
    count++;
    for (int i = 0; i < N; ++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 > N) {
                return -1; // If we can't flip the
                           // entire subarray, its
                           // impossible
            }
            flip ^= 1;
            if (i + K < N) {
                temp[i + K] ^= 1;
            }
        }
    }
 
    return count;
}
     
int main()
{
    int A[] = { 0, 1, 0 };
    int N = sizeof(A) / sizeof(A[0]);
    int K = 1;
    int ans = minKBitFlips(A, K, N);
    cout << ans;
 
    return 0;
}
 
// This code is contributed by suresh07.


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);
    }
}


Python3
def minKBitFlips(A, K):
 
    temp = [0]*len(A)
    count = 0
    flip = 0
    for i in range(len(A)):
        flip ^= temp[i]
        if (A[i] == flip):
           
            # If we must flip the
            # subarray starting here...
            count += 1
             
            # We're flipping the subarray from
            # A[i] to A[i+K-1]
            if (i + K > len(A)) :
                return -1
               
                # If we can't flip the
                # entire subarray, its
                # impossible
             
            flip ^= 1
            if (i + K < len(A)):
                temp[i + K] ^= 1
 
    return count
     
A = [ 0, 1, 0 ]
K = 1
ans = minKBitFlips(A, K)
print(ans)
 
# This code is contributed by divyesh072019.


Javascript


C#
/*package whatever //do not write package name here */
 
using System;
 
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);
        Console.Write(ans);
    }
}
 
// This code is contributed by shivanisinghss2110


输出
2

时间复杂度: O(N)
辅助空间: O(N)

方法 2:- 滑动窗口

C++

#include 
using namespace std;
 
int minKBitFlips(int A[], int K, int N)
{
   
    // store previous flip events
    queue flip;
    int count = 0;
    for (int i = 0; i < N; i++)
    {
       
        // remove an item which is out range of window.
        if (flip.size() > 0 && (i - flip.front() >= K)) {
            flip.pop();
        }
       
        /*
         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 >= N) {
                return -1;
            }
            flip.push(i); // insert
            count++;
        }
    }
    return count;
}
     
int main()
{
    int A[] = { 0, 1, 0 };
    int N = sizeof(A) / sizeof(A[0]);
    int K = 1;
    int ans = minKBitFlips(A, K, 3);
    cout << ans;
 
    return 0;
}
 
// This code is contributed by divyeshrabadiya07.

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);
    }
}

蟒蛇3

def minKBitFlips(A, K, N):
     
    # Store previous flip events
    flip = []
    count = 0
     
    for i in range(N):
         
        # Remove an item which is out range of window.
        if (len(flip) > 0 and (i - flip[0] >= K)):
            flip.pop(0)
     
        """
        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 == len(flip) % 2):
            if (i + K - 1 >= N):
                return -1
                 
            # Insert
            flip.append(i)
            count += 1
             
    return count
 
# Driver code
A = [ 0, 1, 0 ]
N = len(A)
K = 1
 
ans = minKBitFlips(A, K, 3)
 
print(ans)
 
# This code is contributed by rameshtravel07

C#

using System;
using System.Collections;
class GFG {
     
    static int minKBitFlips(int[] A, int K)
    {
       
        // store previous flip events
        Queue flip = new Queue();
        int count = 0;
        for (int i = 0; i < A.Length; i++)
        {
           
            // remove an item which is out range of window.
            if (flip.Count > 0 && (i - (int)flip.Peek() >= K)) {
                flip.Dequeue();
            }
           
            /*
             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.Count % 2) {
                if (i + K - 1 >= A.Length) {
                    return -1;
                }
                flip.Enqueue(i); // insert
                count++;
            }
        }
        return count;
    }
     
  static void Main() {
    int[] A = { 0, 1, 0 };
    int K = 1;
    int ans = minKBitFlips(A, K);
    Console.WriteLine(ans);
  }
}
 
// This code is contributed by mukesh07.

Javascript


输出
2

复杂性分析:-

时间复杂度: O(N),其中 N 是数组的长度。

空间复杂度: O(N)。

方法3:-贪婪

C++

#include 
using namespace std;
 
int minKBitFlips(int A[], int K, int N)
{
    int temp[N];
    memset(temp, 0, N);
    int count = 0;
    int flip = 0;
    count++;
    for (int i = 0; i < N; ++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 > N) {
                return -1; // If we can't flip the
                           // entire subarray, its
                           // impossible
            }
            flip ^= 1;
            if (i + K < N) {
                temp[i + K] ^= 1;
            }
        }
    }
 
    return count;
}
     
int main()
{
    int A[] = { 0, 1, 0 };
    int N = sizeof(A) / sizeof(A[0]);
    int K = 1;
    int ans = minKBitFlips(A, K, N);
    cout << ans;
 
    return 0;
}
 
// This code is contributed by suresh07.

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);
    }
}

蟒蛇3

def minKBitFlips(A, K):
 
    temp = [0]*len(A)
    count = 0
    flip = 0
    for i in range(len(A)):
        flip ^= temp[i]
        if (A[i] == flip):
           
            # If we must flip the
            # subarray starting here...
            count += 1
             
            # We're flipping the subarray from
            # A[i] to A[i+K-1]
            if (i + K > len(A)) :
                return -1
               
                # If we can't flip the
                # entire subarray, its
                # impossible
             
            flip ^= 1
            if (i + K < len(A)):
                temp[i + K] ^= 1
 
    return count
     
A = [ 0, 1, 0 ]
K = 1
ans = minKBitFlips(A, K)
print(ans)
 
# This code is contributed by divyesh072019.

Javascript


C#

/*package whatever //do not write package name here */
 
using System;
 
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);
        Console.Write(ans);
    }
}
 
// This code is contributed by shivanisinghss2110
输出
2

复杂性分析:-

时间复杂度: O(N),其中 N 是数组的长度。

空间复杂度: O(N)。

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程