To solve this problem, we need to determine the minimum number of swaps required to convert a given string into a palindrome. If the string cannot be converted into a palindrome, we return -1.
Approach
-
Check Palindrome Feasibility: A string can be converted into a palindrome if it has at most one character with an odd frequency (exactly one if the length is odd, zero if even). This is because a palindrome reads the same forwards and backwards, so most characters must appear an even number of times (except for the middle character in odd-length strings).
-
Two-Pointer Technique:
- Use two pointers,
leftstarting at the beginning andrightat the end of the string. - If characters at
leftandrightare the same, move both pointers inward. - If not, find the position
k(betweenleft+1andright) where the character matches the one atleft. Swap the character atkwith the one atrightand increment the swap count. - If no such
kexists (the character atleftis the one with the odd frequency), swap it with the next character and increment the swap count (this moves the odd character towards the center).
- Use two pointers,
Solution Code
def is_palindrome_possible(s):
freq = {}
for char in s:
freq[char] = freq.get(char, 0) + 1
odd_count = 0
for count in freq.values():
if count % 2 != 0:
odd_count += 1
if odd_count > 1:
return False
return True
def min_swaps_to_palindrome(s):
if not is_palindrome_possible(s):
return -1
s_list = list(s)
left = 0
right = len(s_list) - 1
swaps = 0
while left < right:
if s_list[left] == s_list[right]:
left += 1
right -= 1
else:
# Find the character matching s_list[left] from right to left
k = right
while k > left and s_list[k] != s_list[left]:
k -= 1
if k == left:
# This character is the odd one; move it to the center
s_list[left], s_list[left + 1] = s_list[left + 1], s_list[left]
swaps += 1
else:
# Swap k and right to match the left character
s_list[k], s_list[right] = s_list[right], s_list[k]
swaps += 1
right -= 1
return swaps
# Example usage
print(min_swaps_to_palindrome("aabb")) # Output: 1
print(min_swaps_to_palindrome("aabcc")) # Output: 1
print(min_swaps_to_palindrome("abcde")) # Output: -1
print(min_swaps_to_palindrome("aaabb")) # Output: 2
Explanation
- Feasibility Check: The function
is_palindrome_possiblechecks if the string can be converted into a palindrome by counting character frequencies. - Two-Pointer Technique: The
min_swaps_to_palindromefunction uses two pointers to find matching characters from both ends. If a match is found, it moves the pointers inward. If not, it either swaps to find a match or moves the odd character towards the center. - Efficiency: The algorithm runs in O(n²) time (due to the inner loop to find the matching character), which is acceptable for most practical purposes given typical input sizes.
This approach ensures we find the minimum number of swaps to convert the string into a palindrome (if possible).)


作者声明:本文包含人工智能生成内容。