通过翻转除任何 1 之外的所有位,以最少的操作将给定的二进制字符串转换为另一个
给定两个二进制字符串s1和s2 ,任务是计算将字符串s1 转换为 s2的最少操作。在一个操作中,可以选择一个设置位,并且翻转除此之外的所有其他位。如果无法转换 s1-> s2 print -1 。
例子:
Input: s1 = “100010111” s2 = “101101100”
Output: 3
Explanation:
In the first operation hold 1 at 6 th index and convert remaining to logical NOT: 100010111→011101100 .
In the second operation hold 1 at 1st index and convert remaining to logical NOT: 011101100→110010011.
In the third operation hold 1 at 0th index and convert remaining to logical NOT: 110010011→101101100.
So 3 operations.
Input: s1=”11111″ s2 = “00000”
Output: -1
处理方法:可以看出,在两次操作字符串保持原样后,选择相同的索引为 1。所以应该为每个操作选择不同的索引,这样字符串s1 中的“10”可以通过两个操作转换为字符串 s2 中的字符串“ 01” 。所以答案取决于最小化字符串s1 和 s2 中“10”和“01”的数量。如果在任何索引处“0(s1) – 1(s2)” && “1(s1) – 0(s2)”数量相等,则答案为 else -1。
“01” (on choosing 1 at index1) -> “11”(on choosing 1 at index2) -> “10”
Using this conclusion:
It can be even possible that minimum “0(s1) – 1(s2) ” && “1(s1) – 0(s2)” pairs can be obtained by doing 1 operation initially. In the cases where 1 (s1)-> 1(s2) or 1(s1) -> 0(s2).
请按照以下步骤解决此问题:
- 初始化变量res = INT_MAX
- 初始化变量ops1= -1以存储将字符串s1 转换为 s2所需的操作,无需任何修改。
- 现在检查是否可以通过在(1(s1)-> 1(s2))的情况下进行 1 次初始修改来最小化操作。
- 将操作存储在ops2变量中,并通过执行min(res,ops2)将最小值存储在res中。
- 现在检查是否可以通过在(1(s1)-> 0(s2))的情况下进行 1 次初始修改来最小化操作。
- 将操作存储在ops3变量中,并通过执行min(res,ops3)将最小值存储在res中。
- 如果res等于INT_MAX ,则意味着无法转换字符串s1 -> s2 所以打印 -1。
- 否则打印res 。
下面是上述方法的实现:
C++14
// C++ program for the above approach
#include
using namespace std;
// Function to count the "0(s1)-1(s2)"
// && "1(s1)- 0(s2)" pairs
int count_operations(string s1, string s2)
{
int n = s1.size();
// Initializing to 0 initially
int cnt10 = 0, cnt01 = 0;
for (int i = 0; i < n; i++) {
if (s1[i] != s2[i]) {
if (s1[i] == '0')
cnt01++;
else
cnt10++;
}
}
// Equal 0(s1)-1(s2) and 1(s1)- 0(s2) pairs
// To convert 1 pair 2 operations are required
// so 2 * cnt01
if (cnt01 == cnt10)
return 2 * cnt01;
return -1;
}
// Function to do one operation of
// modifying the string s1
bool modify_string(string& s1, string& s2,
char c)
{
int n = s1.size();
int idx = -1;
// Find the index of occurrence of
// 1(s1)- c(s2) in s1
for (int i = 0; i < n; i++) {
if (s1[i] == '1' && s2[i] == c) {
// Break if found
idx = i;
break;
}
}
if (idx == -1)
return 0;
// Flip the remaining except that index
for (int i = 0; i < n; i++) {
if (i == idx)
continue;
if (s1[i] == '1')
s1[i] = '0';
else
s1[i] = '1';
}
return 1;
}
// Function to find the minimum operations
// to convert the string s1 to string s2
int find_min_operations(string s1, string s2)
{
int res = INT_MAX;
// Case -1 Initial strings itself
int ops1 = count_operations(s1, s2);
if (ops1 != -1)
res = min(res, ops1);
string a = s1, b = s2;
// Case -2 Doing 1 modification initially
// for 1(s1)-1(s2)
if (modify_string(a, b, '1')) {
int ops2 = count_operations(a, b);
// Take minimum
if (ops2 != -1)
res = min(res, 1 + ops2);
}
// Case-3 doing 1 modification initially
// for 1(s1) - 0(s2)
a = s1, b = s2;
if (modify_string(a, b, '0')) {
int ops3 = count_operations(a, b);
// Take minimum
if (ops3 != -1)
res = min(res, 1 + ops3);
}
if (res == INT_MAX)
return -1;
else
return res;
}
// Driver code
int main()
{
string s1 = "100010111";
string s2 = "101101100";
// Function call
cout << find_min_operations(s1, s2) << endl;
return 0;
}
Python3
# Python program for the above approach
INT_MAX = 2147483647;
# Function to count the "0(s1)-1(s2)"
# && "1(s1)- 0(s2)" pairs
def count_operations (s1, s2):
n = len(s1);
# Initializing to 0 initially
cnt10 = 0
cnt01 = 0;
for i in range(n):
if (s1[i] != s2[i]):
if (s1[i] == '0'):
cnt01 += 1
else:
cnt10 += 1
# Equal 0(s1)-1(s2) and 1(s1)- 0(s2) pairs
# To convert 1 pair 2 operations are required
# so 2 * cnt01
if (cnt01 == cnt10):
return 2 * cnt01;
return -1;
# Function to do one operation of
# modifying the let s1
def modify_string (s1, s2, c):
n = len(s1);
idx = -1;
# Find the index of occurrence of
# 1(s1)- c(s2) in s1
for i in range(n):
if (s1[i] == '1' and s2[i] == c):
# Break if found
idx = i;
break;
if (idx == -1):
return 0;
# Flip the remaining except that index
for i in range(n):
if (i == idx):
continue;
if (s1[i] == '1'):
s1[i] = '0';
else:
s1[i] = '1';
return 1;
# Function to find the minimum operations
# to convert the let s1 to let s2
def find_min_operations (s1, s2):
res = 10 ** 9;
# Case -1 Initial strings itself
ops1 = count_operations(s1, s2);
if (ops1 != -1):
res = min(res, ops1);
a = s1
b = s2;
# Case -2 Doing 1 modification initially
# for 1(s1)-1(s2)
if (modify_string(a, b, '1')):
ops2 = count_operations(a, b);
# Take minimum
if (ops2 != -1):
res = min(res, 1 + ops2);
# Case-3 doing 1 modification initially
# for 1(s1) - 0(s2)
a = s1
b = s2;
if (modify_string(a, b, '0')):
ops3 = count_operations(a, b);
# Take minimum
if (ops3 != -1):
res = min(res, 1 + ops3);
if (res == 10 ** 9):
return -1;
else:
return res;
# Driver code
s1 = "100010111";
s2 = "101101100";
s1 = list(s1);
s2 = list(s2);
# Function call
print(find_min_operations(s1, s2));
# This code is contributed by gfgking
C#
// C# program for the above approach
using System;
class GFG {
// Function to count the "0(s1)-1(s2)"
// && "1(s1)- 0(s2)" pairs
static int count_operations(string s1, string s2)
{
int n = s1.Length;
// Initializing to 0 initially
int cnt10 = 0, cnt01 = 0;
for (int i = 0; i < n; i++) {
if (s1[i] != s2[i]) {
if (s1[i] == '0')
cnt01++;
else
cnt10++;
}
}
// Equal 0(s1)-1(s2) and 1(s1)- 0(s2) pairs
// To convert 1 pair 2 operations are required
// so 2 * cnt01
if (cnt01 == cnt10)
return 2 * cnt01;
return -1;
}
// Function to do one operation of
// modifying the string s1
static int modify_string(ref string s1, ref string s2,
char c)
{
int n = s1.Length;
char[] str1 = s1.ToCharArray();
char[] str2 = s2.ToCharArray();
int idx = -1;
// Find the index of occurrence of
// 1(s1)- c(s2) in s1
for (int i = 0; i < n; i++) {
if (str1[i] == '1' && str2[i] == c) {
// Break if found
idx = i;
break;
}
}
if (idx == -1)
return 0;
// Flip the remaining except that index
for (int i = 0; i < n; i++) {
if (i == idx)
continue;
if (str1[i] == '1')
str1[i] = '0';
else
str1[i] = '1';
}
s1 = new string(str1);
s2 = new string(str2);
return 1;
}
// Function to find the minimum operations
// to convert the string s1 to string s2
static int find_min_operations(string s1, string s2)
{
int res = Int32.MaxValue;
// Case -1 Initial strings itself
int ops1 = count_operations(s1, s2);
if (ops1 != -1)
res = Math.Min(res, ops1);
string a = s1, b = s2;
// Case -2 Doing 1 modification initially
// for 1(s1)-1(s2)
if (modify_string(ref a, ref b, '1') > 0) {
int ops2 = count_operations(a, b);
// Take minimum
if (ops2 != -1)
res = Math.Min(res, 1 + ops2);
}
// Case-3 doing 1 modification initially
// for 1(s1) - 0(s2)
a = s1;
b = s2;
if (modify_string(ref a, ref b, '0') > 0) {
int ops3 = count_operations(a, b);
// Take minimum
if (ops3 != -1)
res = Math.Min(res, 1 + ops3);
}
if (res == Int32.MaxValue)
return -1;
else
return res;
}
// Driver code
public static void Main()
{
string s1 = "100010111";
string s2 = "101101100";
// Function call
Console.WriteLine(find_min_operations(s1, s2));
}
}
// This code is contributed by ukasp.
Javascript
Java
// Java program for the above approach
import java.util.*;
public class GFG {
// Function to count the "0(s1)-1(s2)"
// && "1(s1)- 0(s2)" pairs
static int count_operations(String s1, String s2)
{
int n = s1.length();
// Initializing to 0 initially
int cnt10 = 0, cnt01 = 0;
for (int i = 0; i < n; i++) {
if (s1.charAt(i) != s2.charAt(i)) {
if (s1.charAt(i) == '0')
cnt01++;
else
cnt10++;
}
}
// Equal 0(s1)-1(s2) and 1(s1)- 0(s2) pairs
// To convert 1 pair 2 operations are required
// so 2 * cnt01
if (cnt01 == cnt10)
return 2 * cnt01;
return -1;
}
// Function to do one operation of
// modifying the string s1
static int modify_string(String s1, String s2,
char c)
{
int n = s1.length();
char[] str1 = s1.toCharArray();
char[] str2 = s2.toCharArray();
int idx = -1;
// Find the index of occurrence of
// 1(s1)- c(s2) in s1
for (int i = 0; i < n; i++) {
if (str1[i] == '1' && str2[i] == c) {
// Break if found
idx = i;
break;
}
}
if (idx == -1)
return 0;
// Flip the remaining except that index
for (int i = 0; i < n; i++) {
if (i == idx)
continue;
if (str1[i] == '1')
str1[i] = '0';
else
str1[i] = '1';
}
s1 = new String(str1);
s2 = new String(str2);
return 1;
}
// Function to find the minimum operations
// to convert the string s1 to string s2
static int find_min_operations(String s1, String s2)
{
int res = Integer.MAX_VALUE;
// Case -1 Initial strings itself
int ops1 = count_operations(s1, s2);
ops1 /= 2;
if (ops1 != -1)
res = Math.min(res, ops1);
String a = s1, b = s2;
// Case -2 Doing 1 modification initially
// for 1(s1)-1(s2)
if (modify_string(a, b, '1') > 0) {
int ops2 = count_operations(a, b);
// Take minimum
if (ops2 != -1)
res = Math.min(res, 1 + ops2);
}
// Case-3 doing 1 modification initially
// for 1(s1) - 0(s2)
a = s1;
b = s2;
if (modify_string(a, b, '0') > 0) {
int ops3 = count_operations(a, b);
// Take minimum
if (ops3 != -1)
res = Math.min(res, 1 + ops3);
}
if (res == Integer.MAX_VALUE)
return -1;
else
return res;
}
// Driver code
public static void main(String args[])
{
String s1 = "100010111";
String s2 = "101101100";
// Function call
System.out.println(find_min_operations(s1, s2));
}
}
// This code is contributed by Samim Hossain Mondal.
3
时间复杂度: O(N) 其中 N 是字符串的长度。
空间复杂度: O(N)