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. Any two characters may be swapped, even if they are not adjacent.
For example:
s = "111000"
should return 1
. We can swap positions 1 and 4: "111000" -> "101010"
.s = "010"
should return 0
. The string is already alternating.s = "1110"
should return -1
. It's not possible to make this string alternating.Write a function to solve this problem efficiently. Consider edge cases and explain the time and space complexity of your solution.
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force method for this problem involves checking every single possible arrangement of the binary string to see if it alternates. We want to find out, for each possible arrangement, how many swaps it takes to get to the alternating pattern and then pick the arrangement that takes the fewest swaps.
Here's how the algorithm would work step-by-step:
def min_swaps_alternating(binary_string):
string_length = len(binary_string)
# Generate alternating strings starting with 0 and 1
start_zero_string = "".join(['0' if i % 2 == 0 else '1' for i in range(string_length)])
start_one_string = "".join(['1' if i % 2 == 0 else '0' for i in range(string_length)])
# Count differences for string starting with 0
diff_zero_count = 0
for i in range(string_length):
if binary_string[i] != start_zero_string[i]:
diff_zero_count += 1
# Count differences for string starting with 1
diff_one_count = 0
for i in range(string_length):
if binary_string[i] != start_one_string[i]:
diff_one_count += 1
# Calculate swaps (half the differences)
swaps_zero = diff_zero_count // 2
swaps_one = diff_one_count // 2
# Return the minimum swaps
return min(swaps_zero, swaps_one)
To find the fewest swaps to make a binary string alternating, we avoid checking every possibility. Instead, we consider only two alternating patterns and count how many swaps each would need. The approach then picks the pattern requiring the fewer swaps.
Here's how the algorithm would work step-by-step:
def min_swaps_to_make_alternating(binary_string):
string_length = len(binary_string)
swaps_starting_with_zero = 0
swaps_starting_with_one = 0
# Count swaps needed to make the string start with '0'.
for i in range(string_length):
if i % 2 == 0:
if binary_string[i] == '1':
swaps_starting_with_zero += 1
else:
if binary_string[i] == '0':
swaps_starting_with_zero += 1
# Count swaps needed to make the string start with '1'.
for i in range(string_length):
if i % 2 == 0:
if binary_string[i] == '0':
swaps_starting_with_one += 1
else:
if binary_string[i] == '1':
swaps_starting_with_one += 1
# Find the minimum swaps between the two possible alternating strings
return min(swaps_starting_with_zero, swaps_starting_with_one)
Case | How to Handle |
---|---|
Empty string input | Return 0 since an empty string is already considered alternating. |
String with only one character | Return 0 because a single-character string is already alternating. |
String with all '0' characters | Calculate swaps to make it '1010...' and '0101...' then return the minimum. |
String with all '1' characters | Calculate swaps to make it '1010...' and '0101...' then return the minimum. |
String already alternating ('101010...') | Return 0 as no swaps are needed. |
Very long string (performance considerations) | Ensure the algorithm has O(n) time complexity to efficiently handle long strings. |
String of even length that cannot be perfectly alternated | The algorithm calculates the minimum swaps required for both alternating patterns, providing a best-case result even if perfect alternation is impossible. |
String with a mix of '0' and '1' where one character is dominant | The solution considers both '0101...' and '1010...' patterns, accommodating skewed distributions. |