My code:
public class Solution {
public List<String> generatePalindromes(String s) {
List<String> ret = new ArrayList<String>();
if (s == null || s.length() == 0) {
return ret;
}
HashMap<Character, Integer> map = new HashMap<Character, Integer>();
int counter = 0;
for (int i = 0; i < s.length(); i++) {
char curr = s.charAt(i);
if (!map.containsKey(curr)) {
map.put(curr, 1);
}
else {
map.put(curr, map.get(curr) + 1);
}
}
StringBuilder sb = new StringBuilder();
String center = "";
for (Character c : map.keySet()) {
if (map.get(c) % 2 != 0) {
counter++;
if (counter > 1) {
return ret;
}
center = "" + c;
}
for (int i = 0; i < map.get(c) / 2; i++) {
sb.append(c);
}
}
char[] nums = sb.toString().toCharArray();
List<String> half = permutation(nums);
for (String h : half) {
ret.add(h + center + new StringBuilder(h).reverse());
}
return ret;
}
private List<String> permutation(char[] nums) {
List<String> ret = new ArrayList<String>();
if (nums.length == 0) {
ret.add("");
return ret;
}
Arrays.sort(nums);
boolean[] mark = new boolean[nums.length];
dfs(nums, mark, new StringBuilder(), ret);
return ret;
}
private void dfs(char[] nums, boolean[] mark, StringBuilder path, List<String> ret) {
if (path.length() >= nums.length) {
ret.add(path.toString());
return;
}
int len = path.length();
for (int i = 0; i < nums.length; i++) {
if (mark[i]) {
continue;
}
else if (i > 0 && nums[i] == nums[i - 1] && !mark[i - 1]) {
continue;
}
else {
path.append(nums[i]);
mark[i] = true;
dfs(nums, mark, path, ret);
path.setLength(len);
mark[i] = false;
}
}
}
}
自己做了出来。
其实这道题目的思路还是很明显的。
找出其中一半,然后另一半是这一半的reverse,再拼起来。
同时考虑奇数次的情况,存一个中心字母。
我们拿到一半的字母时,就是一个简单的 permutation II 问题了。
当然要注意。如果输入数组长度为0,
这个时候,返回的 list要插入一个元素 "", 空字符。
因为他可能还存在中心节点,要让遍历继续下去,拿到这个解。
比如,总输入是 : "a", 就需要这个细节来处理。
Anyway, Good luck, Richardo! -- 09/19/2016