Smallest Palindromic Rearrangement I
MediumUpdated: Sep 14, 2025
Practice on:
Problem
You are given a palindromic string s.
Return the lexicographically smallest palindromic permutation of s.
Examples
Example 1
Input: s = "z"
Output: "z"
Explanation:
A string of only one character is already the lexicographically smallest
palindrome.
Example 2
Input: s = "babab"
Output: "abbba"
Explanation:
Rearranging `"babab"` -> `"abbba"` gives the smallest lexicographic
palindrome.
Example 3
Input: s = "daccad"
Output: "acddca"
Explanation:
Rearranging `"daccad"` -> `"acddca"` gives the smallest lexicographic
palindrome.
Constraints
1 <= s.length <= 10^5sconsists of lowercase English letters.sis guaranteed to be palindromic.
Method 1 – Greedy Character Placement
Intuition
To get the lexicographically smallest palindromic permutation, place the smallest available characters at the start and end, and the next smallest, and so on. If the length is odd, the center is the remaining odd-count character.
Approach
- Count the frequency of each character in s.
- For each character in lex order, place half its count at the start and half at the end (mirrored).
- If there is a character with an odd count, place it in the center.
- Return the constructed palindrome.
Code
C++
#include <string>
#include <vector>
using namespace std;
class Solution {
public:
string smallestPalindrome(string s) {
vector<int> cnt(26);
for (char c : s) cnt[c-'a']++;
string left = "", mid = "";
for (int i = 0; i < 26; ++i) {
if (cnt[i] % 2) mid += (char)('a'+i);
left += string(cnt[i]/2, 'a'+i);
}
string right = left; reverse(right.begin(), right.end());
return left + mid + right;
}
};
Java
class Solution {
public String smallestPalindrome(String s) {
int[] cnt = new int[26];
for (char c : s.toCharArray()) cnt[c-'a']++;
StringBuilder left = new StringBuilder(), mid = new StringBuilder();
for (int i = 0; i < 26; ++i) {
if (cnt[i] % 2 == 1) mid.append((char)('a'+i));
for (int j = 0; j < cnt[i]/2; ++j) left.append((char)('a'+i));
}
String right = left.reverse().toString();
left.reverse();
return left.toString() + mid.toString() + right;
}
}
Python
class Solution:
def smallestPalindrome(self, s: str) -> str:
from collections import Counter
cnt = Counter(s)
left, mid = [], ''
for ch in sorted(cnt):
if cnt[ch] % 2:
mid = ch
left.append(ch * (cnt[ch]//2))
return ''.join(left) + mid + ''.join(left)[::-1]
Complexity
- ⏰ Time complexity:
O(n), where n is the length of s. Each character is processed a constant number of times. - 🧺 Space complexity:
O(n), for the output string and counters.