Problem Description
Given an even‐length string s we call it an “anti‐palindrome” if for every index i the character s[i] is not equal to s[n–i–1]. You can rearrange s by swapping any two characters any number of times. Return a rearranged string that is anti‐palindromic and, among all valid rearrangements, is the lexicographically smallest. If no valid rearrangement exists, return "-1".
Key Insights
- An anti‐palindrome requires that every character at position i is different from its mirror position.
- A necessary (and sufficient) condition is that no character appears more than n/2 times.
- A natural starting point is to sort s so that we work with characters in lexicographic order.
- We can “reserve” the first half of the final string (which determines lexicographic minimality) as the smallest n/2 characters.
- The second half must be assigned (in an order we can choose arbitrarily) from the remaining characters but with the extra constraint: if the left half is fixed as sorted[0…n/2–1] then for each pair the character placed in the mirror position must be different.
- Pairing: if we denote left = sorted[0…n/2–1] and let right be the multiset of remaining characters (originally sorted), then note that in the final candidate the mirror of left[i] will be the element placed at index n-i-1. If we “build” the second half in order (positions n/2 to n–1) then the pairing works out as: for j from 0 to n/2–1, the character at second_half[j] will match with left[n/2-j-1].
- To obtain the lexicographically smallest overall answer, we choose the left half as sorted first n/2 characters and, for the second half, for each position we greedily pick the smallest available character from the right multiset that does not equal the “forbidden” character (the corresponding element from left).
- If at any step no valid choice exists the answer is "-1".
Space and Time Complexity
Time Complexity: O(n log n) (sorting dominates; the greedy selection over a set of at most 26 unique characters runs in O(n)) Space Complexity: O(n) (to store the candidate rearrangement and frequency data)
Solution
We first check if any character appears more than n/2 times – if yes, we immediately return "-1". Then, we sort the string to easily obtain the lexicographically smallest order. We reserve the first n/2 characters to form the left half. For the right half we keep a multiset (or sorted list) of the remaining n/2 characters.
While constructing the second half (which is not fixed in place in the final candidate because the pairing is reversed), we note that the pairing rule is: for each j from 0 to n/2–1, the character assigned at position j of the second half (which will go to overall index n/2+j) is paired with left[n/2–j–1]. For each such pair we choose the smallest available character from the right multiset that is not equal to the corresponding left character. This greedy pick ensures that the final string is lexicographically smallest.
Finally, the answer is obtained by concatenating the fixed left half and the constructed right half.
Code Solutions
Below are sample code solutions in Python, JavaScript, C++, and Java with detailed line-by-line comments.