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

📅  最后修改于: 2021-05-17 21:28:35             🧑  作者: 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}的组数比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


输出
From 1 to 2
From 6 to 7

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