给定两个长度为N 的二进制字符串A和B ,任务是通过重复翻转A的前缀来将字符串A转换为B ,即 反转所选前缀中位的出现顺序。打印所需的翻转次数和所有前缀的长度。
例子:
Input: A = “01”, B = “10”
Output:
3
1 2 1
Explanation:
Operation 1: Select the prefix of length 1 from the string A (= “01”). Flipping the prefix “0” modifies the string to “11”.
Operation 2: Select the prefix of length 2 from the string A (= “11”). Flipping the prefix “11” modifies the string to “00”.
Operation 3: Select the prefix of length 1 from the string A (= “00”). Flipping the prefix “0” to “1” modifies the string to “10”, which is the same as the string B.
Therefore, the total number of operations required is 3.
Input: A = “0”, B = “1”
Output:
1
1
方法:给定的问题可以通过逐个固定位来解决。要解决的第i个比特,当A [i]和B [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.
Javascript
3
1 2 1
时间复杂度: O(N 2 )
辅助空间: O(N)
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live