📌  相关文章
📜  通过翻转前缀最小次数将二进制字符串转换为另一个

📅  最后修改于: 2021-04-17 15:32:44             🧑  作者: Mango

给定两个长度为N的二进制字符串AB ,任务是通过反复翻转A的前缀将字符串A转换为B ,即 反转所选前缀中位的出现顺序。打印所需的翻转次数和所有前缀的长度。

例子:

方法:可以通过一对一固定位来解决给定的问题。要固定第i,当A [i]B [i]不相等时,请翻转长度为i的前缀,然后翻转长度为1的前缀。现在,翻转长度i的前缀。这三个操作不会更改A中的任何其他位。在A [i]不等于B [i]的所有索引处执行这些操作。 由于每位使用3个操作,因此总共将使用3 * N个操作。

为了使操作次数最少,可以通过以相反的顺序一对一地固定位来修改上述方法。要解决i比特,无论是必需的I I需要被翻转长度的前缀或所述第一比特,然后长度的前缀被翻转。但是以相反的顺序,以前固定的位不会通过此过程再次翻转,并且每个位最多需要2个操作。因此,所需的最小操作数为2 * N。

下面是上述方法的实现:

C++14
// C++ program for the above approach
#include 
using namespace std;
 
// Function to count minimum number
// of operations required to convert
// string a to another string b
void minOperations(string a, string b, int n)
{
    // Store the lengths of each
    // prefixes selected
    vector ops;
 
    // Traverse the string
    for (int i = n - 1; i >= 0; i--) {
        if (a[i] != b[i]) {
 
            // If first character
            // is same as b[i]
            if (a[0] == b[i]) {
 
                // Insert 1 to ops[]
                ops.push_back(1);
 
                // And, flip the bit
                a[0] = '0' + !(a[0] - '0');
            }
 
            // Reverse the prefix
            // string of length i + 1
            reverse(a.begin(), a.begin() + i + 1);
 
            // Flip the characters
            // in this prefix length
            for (int j = 0; j <= i; j++) {
                a[j] = '0' + !(a[j] - '0');
            }
 
            // Push (i + 1) to array ops[]
            ops.push_back(i + 1);
        }
    }
 
    // Print the number of operations
    cout << ops.size() << "\n";
 
    // Print the length of
    // each prefixes stored
    for (int x : ops) {
        cout << x << ' ';
    }
}
 
// Driver Code
int main()
{
    string a = "10", b = "01";
    int N = a.size();
 
    minOperations(a, b, N);
 
    return 0;
}


Java
// Java program for the above approach
import java.io.*;
import java.lang.*;
import java.util.*;
class GFG
{
 
  // Function to count minimum number
  // of operations required to convert
  // string a to another string b
  static void minOperations(String s1, String s2, int n)
  {
 
    char a[] = s1.toCharArray();
    char b[] = s2.toCharArray();
 
    // Store the lengths of each
    // prefixes selected
    ArrayList ops = new ArrayList<>();
 
    // Traverse the string
    for (int i = n - 1; i >= 0; i--) {
      if (a[i] != b[i]) {
 
        // If first character
        // is same as b[i]
        if (a[0] == b[i]) {
 
          // Insert 1 to ops[]
          ops.add(1);
 
          // And, flip the bit
          a[0] = (a[0] == '0' ? '1' : '0');
        }
 
        // Reverse the prefix
        // string of length i + 1
        reverse(a, 0, i);
 
        // Flip the characters
        // in this prefix length
        for (int j = 0; j <= i; j++) {
          a[j] = (a[j] == '0' ? '1' : '0');
        }
 
        // Push (i + 1) to array ops[]
        ops.add(i + 1);
      }
    }
 
    // Print the number of operations
    System.out.println(ops.size());
 
    // Print the length of
    // each prefixes stored
    for (int x : ops) {
      System.out.print(x + " ");
    }
  }
 
  // Function to reverse a[]
  // from start to end
  static void reverse(char a[], int start, int end)
  {
 
    while (start < end) {
      char temp = a[start];
      a[start] = a[end];
      a[end] = temp;
      start++;
      end--;
    }
  }
 
  // Driver code
  public static void main(String[] args)
  {
 
    String a = "10", b = "01";
    int N = a.length();
 
    minOperations(a, b, N);
  }
}
 
// This code is contributed by Kingash.


C#
// C# program to implement
// the above approach
using System;
using System.Collections.Generic;
 
class GFG
{
 
  // Function to count minimum number
  // of operations required to convert
  // string a to another string b
  static void minOperations(string s1, string s2, int n)
  {
 
    char[] a = s1.ToCharArray();
    char[] b = s2.ToCharArray();
 
    // Store the lengths of each
    // prefixes selected
    List ops = new List();
 
    // Traverse the string
    for (int i = n - 1; i >= 0; i--) {
      if (a[i] != b[i]) {
 
        // If first character
        // is same as b[i]
        if (a[0] == b[i]) {
 
          // Insert 1 to ops[]
          ops.Add(1);
 
          // And, flip the bit
          a[0] = (a[0] == '0' ? '1' : '0');
        }
 
        // Reverse the prefix
        // string of length i + 1
        reverse(a, 0, i);
 
        // Flip the characters
        // in this prefix length
        for (int j = 0; j <= i; j++) {
          a[j] = (a[j] == '0' ? '1' : '0');
        }
 
        // Push (i + 1) to array ops[]
        ops.Add(i + 1);
      }
    }
 
    // Print the number of operations
    Console.WriteLine(ops.Count);
 
    // Print the length of
    // each prefixes stored
    foreach (int x in ops) {
      Console.Write(x + " ");
    }
  }
 
  // Function to reverse a[]
  // from start to end
  static void reverse(char[] a, int start, int end)
  {
 
    while (start < end) {
      char temp = a[start];
      a[start] = a[end];
      a[end] = temp;
      start++;
      end--;
    }
  }
 
  // Driver Code
  public static void Main()
  {
    string a = "10", b = "01";
    int N = a.Length;
 
    minOperations(a, b, N);
  }
}
 
// This code is contributed by souravghosh0416.


输出:
3
1 2 1

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