📌  相关文章
📜  使两个二进制字符串相等的最小交换次数

📅  最后修改于: 2021-04-23 20:57:37             🧑  作者: Mango

给定两个长度相等的二进制字符串,任务是找到使它们相等的最小交换次数。仅允许从两个不同的字符串之间交换两个字符,如果不能使字符串相等,则返回-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种模式:
    1. 00和11,我们可以执行对角线交换,结果将是01 01或1010。在对角线交换的情况下,我们需要形成对以解决这种类型的不成比例问题。恢复一对配对所需的互换是1。
    2. 在11和00处,我们可以执行对角线交换,结果将为01 01或1010。在对角线交换的情况下,我们需要形成对以解决这种类型的不成比例问题。恢复一对配对所需的互换是1。
    3. 10和01,我们可以执行一次垂直交换,结果将是00 11或11 00,并且此类型将转换为类型1或类型2问题,以及另一个对角线交换以使它们相等。我们需要形成一对来解决这种类型的歧义。恢复一对配对所需的互换是2。
  • 从上面的观察中,我们可以遵循下面的贪婪方法:
    1. 计算s1 [i] = 0和s2 [i] = 1的位置(计数0)。在类型1的每对中,我们需要(count0)/ 2个对角互换数。
    2. 计算s1 [i] = 1和s2 [i] = 0的位置(计数1)。在每对类型2中,我们需要(count1)/ 2个对角互换数。
    3. 如果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)