Palindrome Partitioning
22% Accepted
Given a string s, partition s such that every substring of the partition is a palindrome.
Return all possible palindrome partitioning of s.
Have you met this question in a real interview? Yes
Example
Given s = "aab", return:
[
["aa","b"],
["a","a","b"]
]
Tags Expand
- Backtracking
- Depth First Search
思路
- 求所有答案,标准DFS题
- 这个题有很多值得注意的地方,见注释
- 最值得注意的地方就是pos的传入,
- 要先画图画清楚,Pos是如何作用的
- 主要参考第二个答案
public class Solution {
/**
* @param s: A string
* @return: A list of lists of string
*/
public List<List<String>> partition(String s) {
List<List<String>> result = new ArrayList<List<String>>();
if (s == null) {
return result;
}
//不能List<String> list = new ArrayList<String>() 因为List是abstract类型
List<String> list = new ArrayList<String>();
partitionhelper(s, 0, list, result);
return result;
}
public void partitionhelper(String s, int pos, List<String> list, List<List<String>> result) {
if (pos == s.length()) {
//一定是new ArrayList<String>(list),否则的话,就把原来list的地址跟result连起来了,如果list改变,那么result里边的内容也改变了
result.add(new ArrayList<String>(list));
return;
}
for (int i = pos + 1; i <= s.length(); i++) {
String string = s.substring(pos, i);
if (!isPalindrome(string)) {
continue;
}
list.add(string);
partitionhelper(s, i, list, result);
list.remove(list.size() - 1);
}
}
public boolean isPalindrome(String s) {
int beg = 0;
int end = s.length() - 1;
//不必要去设置i++ j-- 多麻烦,一个while就搞定
while (beg < end) {
if (s.charAt(beg) != s.charAt(end)) {
return false;
}
beg++;
end--;
}
return true;
}
}
先生成palindrome的数组,到时候判断不用再去计算一次,省时间
- 注意生成palindrom的数组的时候的动态规划
- state: f[i][j] i到j的substring是不是palindrome
- fcuntion: f[i][j] = f[i+1][j-1] && char(i) == char(j)
- initial: f[i][i] = true, f[i][i + 1] = char(i) == char(i + 1)
- answer: f[i][j]
- 注意下面的顺序,先每次+2地走进行遍历,再+3走进行遍历,而不是先开始遍历,再+2,+3
写循环前,先要想好
直接写下面的方式是错误的,
要先想好动态规划是怎么推到的
既然是这样的形式f[i][j] = f[i+1][j-1]
那么就必然是夹逼,以size的形式,在内环跑完,每次size扩大,
而不是两根指针同向跑
for (int i = 0;...) {
for (int j = i + 2...)
}
for (int j = 2; j < size; j++) {
for (int i = 0; i + len < size; i++)
解法
public class Solution {
/*
* @param s: A string
* @return: A list of lists of string
*/
public List<List<String>> partition(String s) {
// write your code here
List<List<String>> results = new ArrayList<List<String>>();
List<String> list = new ArrayList<String>();
if (s == null || s.equals("")) {
results.add(list);
return results;
}
//check from s.substring(i, j) is a palindrome
boolean[][] isPalindrome = generatePalindromeMatrix(s);
dfs(results, list, s, 0, isPalindrome);
return results;
}
public void dfs(List<List<String>> results, List<String> list, String s, int index, boolean[][] isPalindrome) {
if (index == s.length()) {
results.add(new ArrayList<String>(list));
return;
}
for (int i = index + 1; i <= s.length(); i++) {
String substring = s.substring(index, i);
if (isPalindrome[index][i - 1]) {
list.add(substring);
dfs(results, list, s, i, isPalindrome);
list.remove(list.size() - 1);
}
}
}
public boolean[][] generatePalindromeMatrix(String s) {
if (s == null || s.length() == 0) {
return new boolean[0][0];
}
//f[i][j] is status of palindrome
//i < j
//f[i][j] == (f[i + 1][j - 1] && char[i + 1] == char[j - 1]
//f[i][i] = true
//f[i][i+1] = true if char[i] == char[i + 1]
boolean[][] isPalindrome = new boolean[s.length()][s.length()];
for (int i = 0; i < s.length(); i++) {
isPalindrome[i][i] = true;
if (i >= 1 && s.charAt(i) == s.charAt(i - 1)) {
isPalindrome[i - 1][i] = true;
}
}
for (int i = 2; i < s.length(); i++) {
for (int j = 0; i + j < s.length(); j++) {
if (s.charAt(j) == s.charAt(i + j)) {
isPalindrome[j][i + j] = isPalindrome[j + 1][i + j - 1];
}
}
}
return isPalindrome;
}
}