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中。

 public class Solution {
public List<String> generatePalindromes(String s) {
List<String> result = new ArrayList<>();
if (s == null || s.length() == 0) {
return result;
}
int len = s.length();
Map<Character, Integer> map = new HashMap<>();
if (!isPalindromePermutation(map, s)) {
return result;
}
char mid = '\0';
StringBuilder sb = new StringBuilder();
for (char cur : map.keySet()) {
int num = map.get(cur);
while (num > 1) {
sb.append(cur);
num -= 2;
}
if (num == 1) {
mid = cur;
}
}
Set<String> prefix = new HashSet<String>();
boolean[] visited = new boolean[sb.length()];
dfs(sb, visited, prefix, "");
for (String left : prefix) {
StringBuffer tmp = new StringBuffer(left);
if (mid != '\0') {
tmp.append(mid);
} for (int i = left.length() - 1; i >= 0; i--) {
tmp.append(left.charAt(i));
}
result.add(tmp.toString());
}
return result;
} private void dfs(StringBuilder sb, boolean[] visited, Set<String> result, String prev) {
if (prev.length() == sb.length()) {
result.add(prev);
return;
}
int len = sb.length();
int prevIndex = -1;
for (int i = 0; i < len; i++) {
if (visited[i]) {
continue;
}
if (prevIndex != -1 && sb.charAt(i) == sb.charAt(prevIndex)) {
continue;
}
visited[i] = true;
dfs(sb, visited, result, prev + sb.charAt(i));
visited[i] = false;
prevIndex = i;
}
} private boolean isPalindromePermutation(Map<Character, Integer> map, String s) {
int tolerance = 0;
int len = s.length();
for (int i = 0; i < len; i++) {
char cur = s.charAt(i);
if (!map.containsKey(cur)) {
map.put(cur, 1);
} else {
map.put(cur, map.get(cur) + 1);
}
}
for (char cur : map.keySet()) {
int num = map.get(cur);
if (num % 2 == 1) {
tolerance++;
}
}
return tolerance < 2;
}
}

Palindrome Permutation II 解答的更多相关文章

  1. leetcode 266.Palindrome Permutation 、267.Palindrome Permutation II

    266.Palindrome Permutation https://www.cnblogs.com/grandyang/p/5223238.html 判断一个字符串的全排列能否形成一个回文串. 能组 ...

  2. [LeetCode] Palindrome Permutation II 回文全排列之二

    Given a string s, return all the palindromic permutations (without duplicates) of it. Return an empt ...

  3. 267. Palindrome Permutation II

    题目: Given a string s, return all the palindromic permutations (without duplicates) of it. Return an ...

  4. [LeetCode] 267. Palindrome Permutation II 回文全排列 II

    Given a string s, return all the palindromic permutations (without duplicates) of it. Return an empt ...

  5. LeetCode Palindrome Permutation II

    原题链接在这里:https://leetcode.com/problems/palindrome-permutation-ii/ 题目: Given a string s, return all th ...

  6. [LeetCode#267] Palindrome Permutation II

    Problem: Given a string s, return all the palindromic permutations (without duplicates) of it. Retur ...

  7. [Swift]LeetCode267.回文全排列 II $ Palindrome Permutation II

    Given a string s, return all the palindromic permutations (without duplicates) of it. Return an empt ...

  8. [Locked] Palindrome Permutation I & II

    Palindrome Permutation I Given a string, determine if a permutation of the string could form a palin ...

  9. [LeetCode] Palindrome Permutation I & II

    Palindrome Permutation Given a string, determine if a permutation of the string could form a palindr ...

随机推荐

  1. C++标准库之 Lower_Bound, upper_Bound

    关于二分查找,这绝对是最简单却又最难的实现了,其各种版本号能够參见http://blog.csdn.net/xuqingict/article/details/17335833 在C++的标准库中,便 ...

  2. 逆拓扑排序 HDU2647Reward

    这个题如果用邻接矩阵的话,由于n比较大,会超内存,所以选用邻接表的形式.还有就是这个题有那个等级的问题,一级比一级的福利高,所以不能直接拓扑排序,而是反过来,计算出度,找出度为0的顶点,然后更新出度数 ...

  3. Remoting 的“传递的引用”理解

    WCf是集大成者,具有其他微软的很多技术,其中分布式上很多借助于Remoting,所以研究一下Remoting有助于理解WCF 提到Remoting就不得不涉及到MarshalByRefObject这 ...

  4. HashMap的扩容机制, ConcurrentHashMap和Hashtable主要区别

    源代码查看,有三个常量, static final int DEFAULT_INITIAL_CAPACITY = 16; static final int MAXIMUM_CAPACITY = 1 & ...

  5. CADisplayLink的简单使用

    CADisplayLink类似NSTimer是一个定时器,只不过是一秒会调用60次指定的方法 使用方法: #import "ViewController.h" @interface ...

  6. php curl操作

    <?php // $curl=curl_init(); // $url="http://localhost/cc/get.php?lo=ccc"; // curl_setop ...

  7. Java反射 - 1(得到类对象的几种方法,调用方法,得到包下的所有类)

    通过反射获得对象的方法 准备工作: 有一个User类如下 package o1; /** * Created by yesiming on 16-11-19. */ public class User ...

  8. querySelector选择器

    querySelector选择器可以通过document和element来调用他们 用来代替getElementById var body=document.querySelector("b ...

  9. Ignatius and the Princess I

    算法:搜索+优先队列+(递归输出结果) The Princess has been abducted by the BEelzebub feng5166, our hero Ignatius has ...

  10. CURL_INIT()

    private function http_curl($url,$data=null){ //1.初始化,创建一个新cURL资源 $ch = curl_init(); //2.设置URL和相应的选项 ...