Problem: Palindrome Permutation II

Posted by Marcy on February 18, 2015

Question

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 [].

Solution

TODO

Code

class Solution {
    public List<String> generatePalindromes(String s) {
        List<String> results = new ArrayList<>();
        char[] chars = s.toCharArray();
        int[] charCount = new int[256];
        
        // count the appearance of each char
        for(char c: chars) {
            charCount[c]++;
        }
        
        // get the single char
        List<Character> halfChars = new ArrayList();
        Character single = null;
        for(int i=0; i<256; i++) {
            int count = charCount[i];
            if(count == 0) continue;
            if(count % 2 != 0) {
                if(single != null) return results;
                single = (char)i;
            }
            for(int j=0; j<count/2; j++) {
                halfChars.add((char)i);
            }
        }
        
        if(halfChars.isEmpty() && single != null) {
            results.add(new String(single+""));
            return results;
        }
        
        // depth first search to collect permutations
        List<String> halfPermutations = new ArrayList<>();
        dfsCollecthalfPermutations(halfChars.toArray(new Character[halfChars.size()]), halfPermutations, 0);
        
        // complete all the palindromic permutations
        for(String hp: halfPermutations) {
            StringBuilder sb = new StringBuilder(hp);
            if(single != null) {
                sb.append(single);
            }
            for(int i=hp.length()-1; i>=0; i--) {
                sb.append(hp.charAt(i));
            }
            results.add(sb.toString());
        }
        
        return results;
    }
        
    void dfsCollecthalfPermutations(Character[] chars, List<String> results, int index) {
        if(index == chars.length-1) {
            StringBuilder sb = new StringBuilder();
            for(Character c: chars) {
                sb.append(c);
            }
            results.add(sb.toString());
            return;
        }
        
        boolean[] set = new boolean[256];
        for(int i=index; i<chars.length; i++) {
            // aviud duplicate
            if(set[chars[i]]) continue;
            set[chars[i]] = true;
            swap(chars, index,i);
            dfsCollecthalfPermutations(chars, results, index+1);
            swap(chars, index, i);
        }
    }
    
    void swap(Character[] chars, int idx1, int idx2) {
        char c = chars[idx1];
        chars[idx1] = chars[idx2];
        chars[idx2] = c;
    }
}

Performance

TODO