Minimum number of swaps to make two binary string equal

Given two binary strings of equal length, the task is to find the minimum number of swaps to make them equal. Swapping between two characters from two different strings is only allowed, return -1 if strings can’t be made equal.

Examples:

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

Approach:



    Following observation can be found:

  • Swapping of s1[i] and s2[j] is allowed, so we need to find in which positions two strings are different. If s1[i] and s2[i] are the same, we do not swap them.
  • If s1[i] and s2[i] are not the same then we can find 3 patterns:
    1. 00 and 11, we can perform a diagonal swap and the result will be 01 01 or 10 10. In the case of the diagonal swap, we need to form pairs to solve the disproportion of this type. Swap required to restore a single pair is 1.
    2. 11 and 00, we can perform a diagonal swap and the result will be 01 01 or 10 10. In the case of the diagonal swap, we need to form pairs to solve the disproportion of this type. Swap required to restore a single pair is 1.
    3. 10 and 01, we can perform a vertical swap and the result will be 00 11 or 11 00 and this type will be transformed into type 1 or type 2 problem and another diagonal swap to make them equal. we need to form pair to solve disproportion of this type. Swap required to restore a single pair is 2.
  • From the above observation, we can follow the below greedy method:
    1. Count the positions where s1[i] = 0, and s2[i] = 1 (count0). We need (count0)/2 number of diagonal swaps in each pair of type 1.
    2. Count the positions where s1[i] =1, and s2[i] = 0 (count1). We need (count1)/2 number of diagonal swaps in each pair of type 2.
    3. If both count0 and count1 are even we can output the answer = ((count0) + (count1))/2. If both count0 and count1 is odd, we can have one single pair of type 3 disproportion, so we need 2 extra swaps. Output the answer as ((count0) + (count1))/2 + 2. If one of the count0 and count1 is odd, we can not make two strings equal. As in all cases we need to form pairs, odd count means a single position will be left alone making 2 strings unequal.

Below is the implementation of above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program for
// the above approach
#include <bits/stdc++.h>
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;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# 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

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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

chevron_right


Output:

1

Time Complexity: O(n)



My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.



Improved By : AnkitRai01

Article Tags :
Practice Tags :


1


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.