{x}
blog image

Minimum Number of Swaps to Make the Binary String Alternating

Given a binary string s, return the minimum number of character swaps to make it alternating, or -1 if it is impossible.

The string is called alternating if no two adjacent characters are equal. For example, the strings "010" and "1010" are alternating, while the string "0100" is not.

Any two characters may be swapped, even if they are not adjacent.

 

Example 1:

Input: s = "111000"
Output: 1
Explanation: Swap positions 1 and 4: "111000" -> "101010"
The string is now alternating.

Example 2:

Input: s = "010"
Output: 0
Explanation: The string is already alternating, no swaps are needed.

Example 3:

Input: s = "1110"
Output: -1

 

Constraints:

  • 1 <= s.length <= 1000
  • s[i] is either '0' or '1'.

Solution Explanation: Minimum Number of Swaps to Make the Binary String Alternating

This problem asks for the minimum number of swaps to make a binary string alternating (no consecutive identical characters). The solution uses a counting and greedy approach.

Approach:

  1. Counting 0s and 1s: The algorithm begins by counting the occurrences of '0' and '1' in the input string s. Let's call these counts n0 and n1, respectively.

  2. Check for Impossibility: If the absolute difference between n0 and n1 is greater than 1, it's impossible to create an alternating string. Why? Because you'd need to change more than half the digits, and you can only swap pairs. In this scenario, -1 is returned.

  3. Calculating Swaps: The core logic involves calculating the minimum swaps needed to achieve alternating patterns. There are two possible alternating patterns: starting with '0' or starting with '1'.

  4. calc(c) function: This helper function efficiently calculates the minimum swaps required to make the string alternating, starting with character c ('0' or '1'). It iterates through the string:

    • If the current digit's position (even or odd) doesn't match the expected digit based on c (and the current position's parity), it increments a counter.
    • Finally, it returns counter // 2 (integer division) because each swap involves two positions.
  5. Choosing the Minimum:

    • If n0 and n1 are equal, both alternating patterns are possible, so the algorithm takes the minimum of calc(0) and calc(1).
    • Otherwise (if n0 and n1 are unequal), only the pattern starting with the more frequent digit is considered to minimize swaps.

Time Complexity Analysis:

  • Counting 0s and 1s: O(n) - single pass through the string.
  • calc(c) function: O(n) - single pass through the string.
  • The overall time complexity is dominated by the calc function calls, making it O(n).

Space Complexity Analysis:

The algorithm uses a constant amount of extra space to store variables like n0, n1, and the counter in the calc function. Thus, the space complexity is O(1).

Code Examples (Python):

class Solution:
    def minSwaps(self, s: str) -> int:
        def calc(c: int) -> int:
            return sum((c ^ i & 1) != int(x) for i, x in enumerate(s)) // 2
 
        n0 = s.count("0")
        n1 = len(s) - n0
        if abs(n0 - n1) > 1:
            return -1
        if n0 == n1:
            return min(calc(0), calc(1))
        return calc(0 if n0 > n1 else 1)
 

The code in other languages (Java, C++, Go, TypeScript, JavaScript) follows the same logic and has the same time and space complexity. They differ only in syntax and minor details. The Python version is provided for clarity due to its readability.