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:
- 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.
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 }
时间: 2024-10-10 18:19:37