LC 267 Palindrome Permutation II

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 [].
public class Solution {
    private List<String> list = new ArrayList<String>();
    
    public List<String> generatePalindromes(String s) {
        //判斷一個string可否組成panlindrome, LC 266
        int numOdds = 0;
        int[] map = new int[256];
        for(char c : s.toCharArray()){
            map[c]++;
            // 一個char第一次出現numOdds增長一,第二次出現numOdds減小一。
            // 出現偶數次的char最終對numOdds被抵消。
            // 出現基數詞的char則會讓numOdss加一。
            numOdds = (map[c]&1) == 1 ? numOdds+1 : numOdds - 1; 
        }
        if(numOdds > 1) return list;
        
        //相似於409 Longest Palindrome, 奇數個的那個char單獨考慮,必須放中間。
        //這裏palindrome自己是對稱的,因此只須要找到一半的全排列,利用對稱就能獲得完整的string. 
        String mid = "";
        int halfLen = 0;
        for(int i=0; i<256; i++){
            if(map[i] == 0) continue;
            // 找到那個出現奇數次的字符。
            if((map[i]&1) == 1){
                mid = "" + (char)i;
                map[i]--;
            }
            // 獲得各個字符一半數量的長度
            map[i] = map[i]/2;
            halfLen += map[i];
        }
        // 數字的permutation.
        generatePalindromes("", map, halfLen, mid);
        return list;
    }
    
    public void generatePalindromes(String half, int[] map, int halfLen, String mid){
        // 終止條件,利用palindrome的對稱性輸出結果。
        if(half.length() == halfLen){
            StringBuilder reverse= new StringBuilder(half).reverse();
            list.add(half + mid + reverse);
            return;
        }
        
        for(int i=0; i<256; i++){
            if(map[i] > 0){
                map[i]--;
                generatePalindromes(half+(char)i, map, halfLen, mid);
                map[i]++;
            }
        }
    }
}
相關文章
相關標籤/搜索