Given a string s, return all the palindromic permutations (without duplicates) of it. Return an empty list if no palindromic permutation could be form.
For example:
Given s = “aabb”, return [“abba”, “baab”].
Given s = “abc”, return [].
思路:
1. 列举所有可能。backtrack。
2. 首先需要得到每个字符的频率,然后判断是否只有最多一个奇数个数的字母。把所有字母频率除2得到最终出现在palindrome里的字母个数(不包括奇数个数的字母,因为这个字母必须放在palindrome中间);然后排列组合这个string,把每次排列得到的新的string+mid+string(t.rbegin(),t.rend())。即:只排列左边一半,右边一半是左边的reverse
3. 这道题,先把题目要求简化,即:根据palindrome左右对称特点,只需得到左半边的permutation即可,右边的部分是左边的反转。利用string(rbegin(),rend())即可构造!
4. 这道题就是对string列举所有permutation的题目+判断是否palindrome的题目的组合!
vector<string> generatePalindromes(string s) {
unordered_map<char,int> mm;
for(auto&k:s) mm[k]++;
string t="";
string mid="";
vector<string> res;
for(auto k:mm){
mid+=k.second%2?k:"";
t+=string(k.second/2,k.first);
if(mid.size()>1) return res;
}
//backtracking得到所有的permutation,
permute(t,0,mid,res);
return res;
}
void permute(string&t,int start,string mid,vector<string>& res){
//backtracking=for+recursive
if(start>=t.size()){
res.push_back(t+mid+string(t.rbegin(),t.rend()));
}
for(int i=start;i<t.size();i++){
if(i!=start&&t[i]==t[start]) continue;//去重复
swap(t[i],t[start]);
permute(t,i+1,mid,res);
swap(t[i],t[start]);
}
}