给定两个长度相等的二进制字符串,任务是找到使它们相等的最小交换次数。仅允许从两个不同的字符串之间交换两个字符,如果不能使字符串相等,则返回-1。
例子:
Input: s1 = "0011", s2 = "1111"
Output: 1
Explanation:
Swap s1[0] and s2[1].After swap
s1 = 1011 and s2 = 1011
Input: s1 = "00011", s2 = "01001"
Output: 2
Swap s1[1] and s2[1]. After swap
s1 = 01011, s2 = 00001
Swap s1[3] and s2[1]. After swap,
s1 = 01001, s2 = 01001
方法:
- 可以发现以下观察结果:
- 允许交换s1 [i]和s2 [j],因此我们需要找出两个字符串在哪个位置不同。如果s1 [i]和s2 [i]相同,则不交换它们。
- 如果s1 [i]和s2 [i]不同,那么我们可以找到3种模式:
- 00和11,我们可以执行对角线交换,结果将是01 01或1010。在对角线交换的情况下,我们需要形成对以解决这种类型的不成比例问题。恢复一对配对所需的互换是1。
- 在11和00处,我们可以执行对角线交换,结果将为01 01或1010。在对角线交换的情况下,我们需要形成对以解决这种类型的不成比例问题。恢复一对配对所需的互换是1。
- 10和01,我们可以执行一次垂直交换,结果将是00 11或11 00,并且此类型将转换为类型1或类型2问题,以及另一个对角线交换以使它们相等。我们需要形成一对来解决这种类型的歧义。恢复一对配对所需的互换是2。
- 从上面的观察中,我们可以遵循下面的贪婪方法:
- 计算s1 [i] = 0和s2 [i] = 1的位置(计数0)。在类型1的每对中,我们需要(count0)/ 2个对角互换数。
- 计算s1 [i] = 1和s2 [i] = 0的位置(计数1)。在每对类型2中,我们需要(count1)/ 2个对角互换数。
- 如果count0和count1均是偶数,我们可以输出答案=((count0)+(count1))/ 2。如果count0和count1都为奇数,则我们可以有一对类型3的不成比例,因此我们需要2个额外的交换。将答案输出为((count0)+(count1))/ 2 +2。如果count0和count1之一为奇数,则不能使两个字符串相等。就像在所有情况下我们都需要形成对一样,奇数计数意味着一个单独的位置将被留下来,使2个字符串不相等。
下面是上述方法的实现:
C++
// C++ program for
// the above approach
#include
using namespace std;
// Function to calculate
// min swaps to make
// binary strings equal
int minSwaps(string& s1, string& s2)
{
int c0 = 0, c1 = 0;
for (int i = 0; i < s1.size(); i++) {
// Count of zero's
if (s1[i] == '0' && s2[i] == '1') {
c0++;
}
// Count of one's
else if (s1[i] == '1' && s2[i] == '0') {
c1++;
}
}
// As discussed
// above
int ans = c0 / 2 + c1 / 2;
if (c0 % 2 == 0 && c1 % 2 == 0) {
return ans;
}
else if ((c0 + c1) % 2 == 0) {
return ans + 2;
}
else {
return -1;
}
}
// Driver code
int main()
{
string s1 = "0011", s2 = "1111";
int ans = minSwaps(s1, s2);
cout << ans << '\n';
return 0;
}
Java
// Java program for the above approach
class GFG
{
// Function to calculate
// min swaps to make
// binary strings equal
static int minSwaps(String s1, String s2)
{
int c0 = 0, c1 = 0;
for (int i = 0; i < s1.length(); i++)
{
// Count of zero's
if (s1.charAt(i) == '0' && s2.charAt(i) == '1')
{
c0++;
}
// Count of one's
else if (s1.charAt(i) == '1' && s2.charAt(i) == '0')
{
c1++;
}
}
// As discussed
// above
int ans = c0 / 2 + c1 / 2;
if (c0 % 2 == 0 && c1 % 2 == 0)
{
return ans;
}
else if ((c0 + c1) % 2 == 0)
{
return ans + 2;
}
else
{
return -1;
}
}
// Driver code
public static void main (String[] args)
{
String s1 = "0011", s2 = "1111";
int ans = minSwaps(s1, s2);
System.out.println(ans);
}
}
// This code is contributed by AnkitRai01
Python3
# Python3 program for
# the above approach
# Function to calculate
# min swaps to make
# binary strings equal
def minSwaps(s1, s2) :
c0 = 0; c1 = 0;
for i in range(len(s1)) :
# Count of zero's
if (s1[i] == '0' and s2[i] == '1') :
c0 += 1;
# Count of one's
elif (s1[i] == '1' and s2[i] == '0') :
c1 += 1;
# As discussed above
ans = c0 // 2 + c1 // 2;
if (c0 % 2 == 0 and c1 % 2 == 0) :
return ans;
elif ((c0 + c1) % 2 == 0) :
return ans + 2;
else :
return -1;
# Driver code
if __name__ == "__main__" :
s1 = "0011"; s2 = "1111";
ans = minSwaps(s1, s2);
print(ans);
# This code is contributed by AnkitRai01
C#
// C# program for the above approach
using System;
class GFG
{
// Function to calculate
// min swaps to make
// binary strings equal
static int minSwaps(string s1, string s2)
{
int c0 = 0, c1 = 0;
for (int i = 0; i < s1.Length; i++)
{
// Count of zero's
if (s1[i] == '0' && s2[i] == '1')
{
c0++;
}
// Count of one's
else if (s1[i] == '1' && s2[i] == '0')
{
c1++;
}
}
// As discussed
// above
int ans = c0 / 2 + c1 / 2;
if (c0 % 2 == 0 && c1 % 2 == 0)
{
return ans;
}
else if ((c0 + c1) % 2 == 0)
{
return ans + 2;
}
else
{
return -1;
}
}
// Driver code
public static void Main ()
{
string s1 = "0011", s2 = "1111";
int ans = minSwaps(s1, s2);
Console.WriteLine(ans);
}
}
// This code is contributed by AnkitRai01
输出:
1
时间复杂度: O(n)