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.
1 public class Solution { 2 public List<String> generatePalindromes(String s) { 3 List<String> res = new ArrayList<String>(); 4 List<String> result = new ArrayList<String>(); 5 if (s==null || s.length()==0) return res; 6 int[] countChar = new int[256]; 7 for (int i=0; i<s.length(); i++) { 8 char c = s.charAt(i); 9 countChar[(int)(c-' ')]++; 10 } 11 ArrayList<Character> evenHalf = new ArrayList<Character>(); 12 char oddChar = ' '; 13 int countOdd = 0; 14 for (int i=0; i<256; i++) { 15 char c = (char)(i+' '); 16 int cNum = countChar[i]; 17 if (cNum>0 && cNum%2==0) { //c appears even times 18 for (int ii=1; ii<=cNum/2; ii++) { 19 evenHalf.add(c); 20 } 21 } 22 else if (cNum%2 == 1) {//c appears odd times 23 for (int ii=1; ii<=cNum/2; ii++) { 24 evenHalf.add(c); 25 } 26 oddChar = c; 27 countOdd++; 28 } 29 } 30 if (s.length()%2==0 && countOdd!=0) return res; 31 if (s.length()%2==1 && countOdd!=1) return res; 32 ArrayList<Integer> visited = new ArrayList<Integer>(); 33 halfPermute(res, "", evenHalf, visited); 34 for (String each : res) { 35 String rev = new StringBuffer(each).reverse().toString(); 36 if (s.length()%2==0) result.add(each + rev); 37 else result.add(each + oddChar + rev); 38 } 39 return result; 40 } 41 42 public void halfPermute(List<String> res, String item, ArrayList<Character> evenHalf, ArrayList<Integer> visited) { 43 if (item.length()==evenHalf.size()) { 44 res.add(item); 45 return; 46 } 47 for (int i=0; i<evenHalf.size(); i++) { 48 if (i>0 && evenHalf.get(i)==evenHalf.get(i-1) && !visited.contains(i-1)) continue; 49 if (!visited.contains(i)) { 50 visited.add(i); 51 halfPermute(res, item+evenHalf.get(i), evenHalf, visited); 52 visited.remove(visited.size()-1); 53 } 54 } 55 } 56 }