public List<String> generatePalindromes(String s) {
List<String> res = new ArrayList<>();
if (s == null || s.length() == 0) {
return res;
}
// 1. check if we can form a palindrom
HashMap<Character, Integer> hm = new HashMap<>();
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (hm.containsKey(c)) {
hm.put(c, hm.get(c) + 1);
} else {
hm.put(c, 1);
}
}
String single = "";
StringBuilder sb = new StringBuilder();
for (Map.Entry<Character,Integer> e : hm.entrySet()) {
int num = e.getValue();
if (num % 2 != 0) {
if (!single.equals("")) {// 已经有一个落单的数字了,再看见一个
return res;// 不能组成parlindme,返回空
} else {
single = String.valueOf(e.getKey());
}
}
// 拿出要加到halfchars里(candidates)的字符
num = num / 2; // 因为只算一半,所以线除以二
while (num > 0) {
sb.append(e.getKey());
num--;
}
}
// 2. recursive search for them
String halfchars = sb.toString();
char[] cs = halfchars.toCharArray();
Arrays.sort(cs);
boolean[] visited = new boolean[cs.length];
StringBuilder tmp = new StringBuilder();
dfsHelper(tmp, res, single, 0, cs, visited);
return res;
}
private void dfsHelper(StringBuilder tmp, List<String> res, String single,
int start, char[] cs, boolean[] visited) {
if (tmp.length() == cs.length) {
//生成前半段后,加上中间字符(odd的那个)+reverse前半段
String result = tmp.toString() + single;
res.add(result + tmp.reverse().toString());
tmp.reverse();//记得reverse回原来样子,不然下面会删错char
return;
}
for (int i = 0; i < cs.length; i++) {
if (i != 0 && !visited[i - 1] && cs[i] == cs[i - 1]) {
continue;
}
if (!visited[i]) {
tmp.append(cs[i]);
visited[i] = true;
dfsHelper(tmp, res, single, start + 1, cs, visited);
visited[i] = false;
tmp.deleteCharAt(tmp.length() - 1);//下面指的是这里。
}
}
}