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.
Example 1:
Input: "aabb"
Output: ["abba", "baab"]
Example 2:
Input: "abc"
Output: []
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.
Solution
*這題要列舉所有可能,看來用回朔法(backTrace)比較適合 *需先把沒有解的狀況排除,可以幫助choose,ex. 出現奇數次數的字元有兩個以上,空字串。 計算次數透過hashMap<Character, Integer>。 考慮奇數跟偶數長度組合 若是奇數次數的字元有一個。那並定是在中間,且長度會是奇數:ex aabaa, scasacs 需要額外考慮奇數的tempString內容。 若是偶數一開始為空字串,若是奇數一開始為奇數次數字元,並更新hashMap。 設計helper 有以上理解之後,就可以開始設計helper,首先我們知道回文的特性是左右兩邊剛好是倒過來的關係。所以只有列舉一半。另一半可以透過reverse生成。 1. Choose - > 確認每個字元的count >= 2時,可以choose,拿取之後hashMap裡的count數要-2 2. Observe -> 更新完count之後的hashMap帶入下一次iteration 3. Unchoose -> undo choose,hashMap裡的count數+2
分支完成的條件:
需要考慮奇數跟偶數長度的palindrome (目前的len等於target len/2)。 此時要加入reverse後的另一半。
public static List<String> generatePalindromes(String s) {
HashMap<Character, Integer> map = new HashMap<>();
for (char c : s.toCharArray()) {
map.put(c, map.getOrDefault(c, 0) + 1);
}
int odd = 0;
char mid = 0;
for (Map.Entry<Character, Integer> entry : map.entrySet()) {
if ((entry.getValue() % 2 == 1)) {
odd++;
mid = entry.getKey();
}
}
if (odd > 1 || s == null || s.length() == 0) {
return new ArrayList<String>();
}
ArrayList<String> ret = new ArrayList<>();
String temp = (odd == 1) ? "" + mid : "";
if(mid != 0){
map.put(mid, map.get(mid) - 1);
}
helper(map, ret, temp, (s.length() +1 ) / 2, (odd == 1));
return ret;
}
public static void helper(HashMap<Character, Integer> map, ArrayList<String> finalResult, String tempResult, int len, boolean isOdd) {
if (tempResult.length() == len){
StringBuilder sb = new StringBuilder(tempResult);
if(isOdd){
sb.reverse().deleteCharAt(0).append(tempResult);
tempResult = tempResult.substring(len-1);
}else{
sb.reverse().append(tempResult);
tempResult = "";
}
finalResult.add(sb.toString());
}
for (Map.Entry<Character, Integer> entry : map.entrySet()){
if(entry.getValue() != 0){
//choose
int value = entry.getValue();
map.put(entry.getKey(), value - 2);
tempResult = entry.getKey() + tempResult;
//observe
helper(map, finalResult, tempResult, len, isOdd);
//un-choose
map.put(entry.getKey(), value);
tempResult = tempResult.substring(1);
}
}
}
Last updated
Was this helpful?