class Solution:
def minSwaps(self, s: str) -> int:
n = len(s)
ones = s.count('1')
zeros = n - ones
if abs(ones - zeros) > 1:
return -1
# Helper to count mismatches for a given starting char
def count_swaps(start_with):
swaps = 0
for i, c in enumerate(s):
expected = str((i + start_with) % 2)
if c != expected:
swaps += 1
return swaps // 2
if ones > zeros:
return count_swaps(1)
elif zeros > ones:
return count_swaps(0)
else:
return min(count_swaps(0), count_swaps(1))
class Solution {
public:
int minSwaps(string s) {
int n = s.size();
int ones = count(s.begin(), s.end(), '1');
int zeros = n - ones;
if (abs(ones - zeros) > 1) return -1;
auto count_swaps = [&](int start_with) {
int swaps = 0;
for (int i = 0; i < n; ++i) {
char expected = ((i + start_with) % 2) + '0';
if (s[i] != expected) swaps++;
}
return swaps / 2;
};
if (ones > zeros) return count_swaps(1);
else if (zeros > ones) return count_swaps(0);
else return min(count_swaps(0), count_swaps(1));
}
};
class Solution {
public int minSwaps(String s) {
int n = s.length();
int ones = 0;
for (char c : s.toCharArray()) {
if (c == '1') ones++;
}
int zeros = n - ones;
if (Math.abs(ones - zeros) > 1) return -1;
int swaps0 = 0, swaps1 = 0;
for (int i = 0; i < n; ++i) {
char expected0 = (char)('0' + (i % 2));
char expected1 = (char)('0' + ((i + 1) % 2));
if (s.charAt(i) != expected0) swaps0++;
if (s.charAt(i) != expected1) swaps1++;
}
if (ones > zeros) return swaps1 / 2;
else if (zeros > ones) return swaps0 / 2;
else return Math.min(swaps0, swaps1) / 2;
}
}
var minSwaps = function(s) {
let n = s.length;
let ones = 0;
for (let c of s) if (c === '1') ones++;
let zeros = n - ones;
if (Math.abs(ones - zeros) > 1) return -1;
function countSwaps(startWith) {
let swaps = 0;
for (let i = 0; i < n; ++i) {
let expected = ((i + startWith) % 2).toString();
if (s[i] !== expected) swaps++;
}
return Math.floor(swaps / 2);
}
if (ones > zeros) return countSwaps(1);
else if (zeros > ones) return countSwaps(0);
else return Math.min(countSwaps(0), countSwaps(1));
};
Given a binary string s
(a string containing only '0' and '1'), your task is to determine the minimum number of swaps needed to make s
alternate between '0' and '1'. Alternating means no two adjacent characters are the same, so valid results look like "0101..." or "1010...". Each swap can exchange any two characters (not necessarily adjacent). If it is impossible to make s
alternating, return -1
.
s
can be used only once per swap.-1
.
At first glance, it might seem you need to try all possible swaps, but that would be very inefficient. Instead, start by thinking about what makes a binary string alternating: the characters at even and odd positions must always differ. That means, for a string of length n
, the counts of '0's and '1's must be almost equal (the difference can be at most 1). If not, it's impossible.
Next, consider two possible alternating patterns:
The brute-force approach of generating all permutations is not feasible for large strings, so we look for a pattern-based, counting solution.
-1
(impossible).s[i]
matches the expected character for that pattern. If not, increment the mismatch count.mismatches // 2
.-1
if not possible.This approach is efficient because it avoids trying all permutations and instead leverages the properties of alternating binary strings and counting mismatches.
Let's walk through an example with s = "111000"
:
The key insight is that an alternating binary string must have nearly equal numbers of '0's and '1's, and that each swap can fix two mismatches. By comparing the input string to both possible alternating patterns, we can efficiently count mismatches and compute the minimum number of swaps needed. This avoids brute-force and results in an O(n) solution that is both elegant and efficient.