首页 > 代码库 > Palindrome Permutation II 解答

Palindrome Permutation II 解答

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

Hint:

  1. If a palindromic permutation exists, we just need to generate the first half of the string.
  2. To generate all distinct permutations of a (half of) string, use a similar approach from: Permutations II or Next Permutation.

Answer

这道题思考起来其实不难,就是步骤比较多,要小心。

1. 判断输入是否能有permutation构成palindrome => HashMap或HashSet,这里因为判断完后还有下一步,所以采用Map

2. 根据Map获得first half of the string

3. Backtracking生成first half的permutation

4. 根据生成的permutation,补齐last half

另外解答中处理反转String的方法也值得学习:先利用原String构造一个StringBuffer,然后从后往前遍历原String,将char一一加到StringBuffer中。

 1 public class Solution {
 2     public List<String> generatePalindromes(String s) {
 3         List<String> result = new ArrayList<>();
 4         if (s == null || s.length() == 0) {
 5             return result;
 6         }
 7         int len = s.length();
 8         Map<Character, Integer> map = new HashMap<>();
 9         if (!isPalindromePermutation(map, s)) {
10             return result;
11         }
12         char mid = ‘\0‘;
13         StringBuilder sb = new StringBuilder();
14         for (char cur : map.keySet()) {
15             int num = map.get(cur);
16             while (num > 1) {
17                 sb.append(cur);
18                 num -= 2;
19             }
20             if (num == 1) {
21                 mid = cur;
22             }
23         }
24         Set<String> prefix = new HashSet<String>();
25         boolean[] visited = new boolean[sb.length()];
26         dfs(sb, visited, prefix, "");
27         for (String left : prefix) {
28             StringBuffer tmp = new StringBuffer(left);
29             if (mid != ‘\0‘) {
30                 tmp.append(mid);
31             }
32              
33             for (int i = left.length() - 1; i >= 0; i--) {
34                 tmp.append(left.charAt(i));
35             }
36             result.add(tmp.toString());
37         }
38         return result;
39     }
40     
41     private void dfs(StringBuilder sb, boolean[] visited, Set<String> result, String prev) {
42         if (prev.length() == sb.length()) {
43             result.add(prev);
44             return;
45         }
46         int len = sb.length();
47         int prevIndex = -1;
48         for (int i = 0; i < len; i++) {
49             if (visited[i]) {
50                 continue;
51             }
52             if (prevIndex != -1 && sb.charAt(i) == sb.charAt(prevIndex)) {
53                 continue;
54             }
55             visited[i] = true;
56             dfs(sb, visited, result, prev + sb.charAt(i));
57             visited[i] = false;
58             prevIndex = i;
59         }
60     }
61     
62     private boolean isPalindromePermutation(Map<Character, Integer> map, String s) {
63         int tolerance = 0;
64         int len = s.length();
65         for (int i = 0; i < len; i++) {
66             char cur = s.charAt(i);
67             if (!map.containsKey(cur)) {
68                 map.put(cur, 1);
69             } else {
70                 map.put(cur, map.get(cur) + 1);
71             }
72         }
73         for (char cur : map.keySet()) {
74             int num = map.get(cur);
75             if (num % 2 == 1) {
76                 tolerance++;
77             }
78         }
79         return tolerance < 2;
80     }
81 }

 

Palindrome Permutation II 解答