Description
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 <= 1000s[i]is either'0'or'1'.
Solutions
Solution 1: Counting
First, we count the number of characters 0 and 1 in the string s, denoted as n0 and n1 respectively.
If the absolute difference between n0 and n1 is greater than 1, it is impossible to form an alternating string, so we return -1.
If n0 and n1 are equal, we can calculate the number of swaps needed to convert the string into an alternating string starting with 0 and starting with 1, and take the minimum value.
If n0 and n1 are not equal, we only need to calculate the number of swaps needed to convert the string into an alternating string starting with the character that appears more frequently.
The problem is reduced to calculating the number of swaps needed to convert the string s into an alternating string starting with character c.
We define a function calc(c), which represents the number of swaps needed to convert the string s into an alternating string starting with character c. We traverse the string s, and for each position i, if the parity of i is different from c, we need to swap the character at this position, incrementing the counter by 1. Since each swap makes two positions have the same character, the final number of swaps is half of the counter.
The time complexity is O(n), where n is the length of the string s. The space complexity is O(1).
class Solution: def minSwaps(self, s: str) -> int: def calc(c: int) -> int: return sum((c ^ i & 1) != x for i, x in enumerate(map(int, 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)(code-box)
