给你一个 回文 字符串 s。
返回 s 的按字典序排列的 最小回文排列。
如果一个字符串从前往后和从后往前读都相同,那么这个字符串是一个 回文字符串。
排列是字符串中所有字符的重排。
如果字符串 a 按字典序小于字符串 b,则表示在第一个不同的位置,a 中的字符比 b 中的对应字符在字母表中更靠前。
如果在前 min(a.length, b.length) 个字符中没有区别,则较短的字符串按字典序更小。
示例 1:
输入: s = "z"
输出: "z"
解释:
仅由一个字符组成的字符串已经是按字典序最小的回文。
示例 2:
输入: s = "babab"
输出: "abbba"
解释:
通过重排 "babab" → "abbba",可以得到按字典序最小的回文。
示例 3:
输入: s = "daccad"
输出: "acddca"
解释:
通过重排 "daccad" → "acddca",可以得到按字典序最小的回文。
提示:
1 <= s.length <= 10^5s由小写英文字母组成。- 保证
s是回文字符串。
分析:由于 s 一定是回文字符串,则 s 中出现的字符,一定最多只有一个字符出现次数为奇数,其它所有字符出现次数都是偶数。因此可以遍历 s 字符串,统计所有字符的出现次数,再从字典序由小到大遍历所有字符,按照对称方式从小到大填充字符串。若某个字符出现次数为奇数,则在字符串的中间位置填上该字符。直到把字符串填满。
cpp
class Solution {
public:
string smallestPalindrome(string s) {
int n=s.length(),cnt[30]={0};
string ret=s;
for(int i=0;i<n;++i)
cnt[s[i]-'a']++;
for(int i=0,t=0;i<26;++i)
{
if(!cnt[i])continue;
if(cnt[i]&1)cnt[i]--,ret[n/2]=i+'a';
while(cnt[i]>0)
ret[t]=ret[n-t-1]=i+'a',cnt[i]-=2,t++;
}
return ret;
}
};