1. 程式人生 > >267. Palindrome Permutation II --back tracking 以及palindrome 的優化方法ing

267. Palindrome Permutation II --back tracking 以及palindrome 的優化方法ing

產生input中 所有permutation 中符合 palindrome 的。

Input: "aabb" Output: ["abba", "baab"]

分析: 和47. Permutations II 本質上一樣的,首先字母有重複的,因此為了避免重複解,得先排序。
47題example
Input: [1,1,2]
Output:
[
  [1,1,2],
  [1,2,1],
  [2,1,1]
]

 然而寫了一個類似47的解竟然TLE了,

優化策略1. 統計整個字串中每個字母的個數,如果奇數個的個數>1 ,則所有的permutation 都不可能符合要求。 

做了這個優化後寫了如下code, 但時間複雜度太高,排到了 0.0%了吧,演算法複雜度為o(n!)

 1 class Solution {
 2     public List<String> generatePalindromes(String s) {
 3         List<String> result = new ArrayList<>();
 4         int[] map = new int[128];
 5         if (!canPermutePalindrome(s, map))
 6             return
new ArrayList < > (); 7 char[] ch = s.toCharArray(); 8 Arrays.sort(ch); 9 dfs(new StringBuilder(), result, ch,new boolean[s.length()]); 10 return result; 11 } 12 13 private void dfs(StringBuilder curResult, List<String> result, char[] ch, boolean
[] used){ 14 if(curResult.length() == ch.length){ 15 //System.out.println(curResult); 16 String candid = curResult.toString(); 17 if(isPalindromes(candid)){ 18 result.add(candid); 19 } 20 return; 21 } 22 23 for(int i=0; i<ch.length; i++){ 24 if(used[i] || i>0 && ch[i] == ch[i-1] && !used[i-1]) continue; 25 26 curResult.append(ch[i]); 27 used[i] = true; 28 dfs(curResult,result,ch,used); 29 curResult.setLength(curResult.length()-1); 30 used[i] = false; 31 32 } 33 } 34 35 private boolean isPalindromes(String s){ 36 int len = s.length(); 37 for(int i=0; i<len/2;i++){ 38 if(s.charAt(i) != s.charAt(len-i-1)) return false; 39 } 40 return true; 41 } 42 43 public boolean canPermutePalindrome(String s, int[] map) { 44 int count = 0; 45 for (int i = 0; i < s.length(); i++) { 46 map[s.charAt(i)]++; 47 if (map[s.charAt(i)] % 2 == 0) 48 count--; 49 else 50 count++; 51 } 52 return count <= 1; 53 } 54 }

看了 solution 裡的優化方法, 可以優化到 o(n/2!) 而不是 o(n!) 每次只要build 一半的字串就夠了。