📌  相关文章
📜  使二进制数组元素相同的最小组翻转

📅  最后修改于: 2021-09-08 12:33:06             🧑  作者: Mango

给定一个二进制数组,我们需要将该数组转换为一个包含全 1 或全 0 的数组。我们需要使用最少的组翻转次数来做到这一点。

例子 :

一个朴素的解决方案是遍历数组的两次遍历。我们首先遍历找到0的组数和1的组数,我们找到这两者中的最小值。然后我们遍历数组并在 1 组较少时翻转 1。否则,我们翻转 0。

如何通过一次数组遍历来做到这一点?

一个有效的解决方案基于以下事实:

  • 只有两种类型的组(0 组和 1 组)
  • 要么两组的计数相同,要么计数之间的差值最多为1。例如,在{1, 1, 0, 1, 0, 0}中有两组0和两组1。例如{1, 1, 0, 0, 0, 1, 0, 0, 1, 1},1组的个数比0的个数多1。

基于以上事实,我们可以得出结论,如果我们总是翻转第二组和与第二组相同类型的其他组,我们总是得到正确的答案。在第一种情况下,当组数相同时,我们翻转哪种组类型并不重要,因为两者都会导致正确答案。在第二种情况下,当有多余的时候,通过忽略第一组并从第二组开始,我们将这种情况转换为第一种情况(对于从第二组开始的子数组)并得到正确答案。

C++
// C++ program to find the minimum
// group flips in a binary array
#include 
using namespace std;
 
void printGroups(bool arr[], int n) {
   
  // Traverse through all array elements
  // starting from the second element
  for (int i = 1; i < n; i++) {
     
    // If current element is not same
    // as previous
    if (arr[i] != arr[i - 1]) {
       
      // If it is same as first element
      // then it is starting of the interval
      // to be flipped.
      if (arr[i] != arr[0])
        cout << "From " << i << " to ";
 
      // If it is not same as previous
      // and same as first element, then
      // previous element is end of interval
      else
        cout << (i - 1) << endl;
    }
  }
 
  // Explicitly handling the end of
  // last interval
  if (arr[n - 1] != arr[0])
    cout << (n - 1) << endl;
}
 
int main() {
  bool arr[] = {0, 1, 1, 0, 0, 0, 1, 1};
  int n = sizeof(arr) / sizeof(arr[0]);
  printGroups(arr, n);
  return 0;
}


Java
// Java program to find the minimum
// group flips in a binary array
import java.io.*;
import java.util.*;
 
class GFG {
     
static void printGroups(int arr[], int n)
{
     
    // Traverse through all array elements
    // starting from the second element
    for(int i = 1; i < n; i++)
    {
         
       // If current element is not same
       // as previous
       if (arr[i] != arr[i - 1])
       {
            
           // If it is same as first element
           // then it is starting of the interval
           // to be flipped.
           if (arr[i] != arr[0])
               System.out.print("From " + i + " to ");
            
           // If it is not same as previous
           // and same as first element, then
           // previous element is end of interval
           else
               System.out.println(i - 1);
       }
    }
     
    // Explicitly handling the end of
    // last interval
    if (arr[n - 1] != arr[0])
        System.out.println(n - 1);
}
     
// Driver code
public static void main(String[] args)
{
    int arr[] = {0, 1, 1, 0, 0, 0, 1, 1};
    int n = arr.length;
     
    printGroups(arr, n);
}
}
 
// This code is contributed by coder001


Python3
# Python3 program to find the minimum
# group flips in a binary array
 
def printGroups(arr, n):
     
    # Traverse through all array elements
    # starting from the second element
    for i in range(1, n):
         
        # If current element is not same
        # as previous
        if (arr[i] != arr[i - 1]):
             
            # If it is same as first element
            # then it is starting of the interval
            # to be flipped.
            if (arr[i] != arr[0]):
                print("From", i, "to ", end = "")
 
            # If it is not same as previous
            # and same as the first element, then
            # previous element is end of interval
            else:
                print(i - 1)
 
    # Explicitly handling the end of
    # last interval
    if (arr[n - 1] != arr[0]):
        print(n - 1)
 
# Driver Code
if __name__ == '__main__':
     
    arr = [ 0, 1, 1, 0, 0, 0, 1, 1 ]
    n = len(arr)
     
    printGroups(arr, n)
     
# This code is contributed by Bhupendra_Singh


C#
// C# program to find the minimum
// group flips in a binary array
using System;
 
class GFG{
     
static void printGroups(int []arr, int n)
{
     
    // Traverse through all array elements
    // starting from the second element
    for(int i = 1; i < n; i++)
    {
 
       // If current element is not same
       // as previous
       if (arr[i] != arr[i - 1])
       {
            
           // If it is same as first element
           // then it is starting of the interval
           // to be flipped.
           if (arr[i] != arr[0])
               Console.Write("From " + i + " to ");
            
           // If it is not same as previous
           // and same as first element, then
           // previous element is end of interval
           else
               Console.WriteLine(i - 1);
       }
    }
     
    // Explicitly handling the end
    // of last interval
    if (arr[n - 1] != arr[0])
        Console.WriteLine(n - 1);
}
     
// Driver code
public static void Main(String[] args)
{
    int []arr = { 0, 1, 1, 0, 0, 0, 1, 1 };
    int n = arr.Length;
     
    printGroups(arr, n);
}
}
 
// This code is contributed by amal kumar choubey


Javascript


输出
From 1 to 2
From 6 to 7

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

如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live