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 [].
Hint:
If a palindromic permutation exists, we just need to generate the first half of the string.
To generate all distinct permutations of a (half of) string, use a similar approach from: Permutations II or Next Permutation.
Hide Tags Backtracking
Hide Similar Problems (M) Next Permutation (M) Permutations II (E) Palindrome Permutation
根據提示,我們只要產生一半permutation, 最後把每個permutation reverse一下append它自己之後就可以了。如果有odd char 注意加在中間。比如對於aabbccd,我們先找出d是個odd frequency的char,然後找出一半的string應該是abc,對於abc有的permutation 是: abc, acb, bac, bca, cab, cba. 對於每個permutation, 先加上odd frequency char(if it has) 再reverse自己加到後面就有了palindrome permutation. 比如:abcdcba等。
找odd frequency char的方法跟I一樣。
找permutation的方法和permutation II一樣,注意可能有duplicate char。
class Solution {
public:
vector<string> generatePalindromes(string s) {
vector<string> res;
int odd = 0, singleIdx = -1;
int mp[256] = {0};
for(char c : s){
if(++mp[c]%2 == 1) ++odd;
else --odd;
}
// no palindrom permutation;
if(odd > 1) return res;
string half = "";
//generate half string.
for(int i = 0; i<256; ++i){
half.append(mp[i]/2, char(i));
if(mp[i]%2==1) singleIdx = i;
}
vector<string> permutations;
//get half permutation;
getPermutation(half, 0, permutations);
//reverse each of them and append it to the tail of p.
for(auto p : permutations){
string tmp = p;
reverse(tmp.begin(), tmp.end());
if(singleIdx >= 0 ) p += char(singleIdx);// there is a signle char add it to the middle;
res.push_back(p + tmp);
}
return res;
}
void getPermutation(string halfStr, int pos, vector<string>& strs){
if(pos == halfStr.size()){
strs.push_back(halfStr);
return;
}
for(int i = pos; i<halfStr.size(); ++i){
if(i!=pos && halfStr[i] == halfStr[pos]) continue;
swap(halfStr[i], halfStr[pos]);
getPermutation(halfStr, pos+1, strs);
}
}
};
小note:
把int 轉成char 直接用char(i)
即可。