本题核心思想:
具体可以看代码随想录解释,把这题最简化了。
最好理解:
class Solution {
List<List<String>> res = new ArrayList<>();
LinkedList<String> path = new LinkedList<>();
public List<List<String>> partition(String s) {
backtrack(s, 0);
return res;
}
private void backtrack(String s, int index) {
//索引的位置就是切割字符串的位置,当和字符串长度相同时说明切割到字符串结尾了,此时输出结果
if (s.length() == index) {
res.add(new ArrayList<>(path));
return;
}
for (int i = index; i < s.length(); i ++) {
//判断是否是回文串
if (isPalindrome(s, index, i)) {
//这一步原来是i - index + 1,但是java版的就是i + 1,为啥呢,明天看
String str = s.substring(index, i + 1);
path.add(str);
}else {
continue;
}
backtrack(s, i + 1);
path.removeLast();
}
}
private boolean isPalindrome(String s, int l, int r) {
if (r - l < 0) return false;
while (l <=r) {
if (s.charAt(l) != s.charAt(r)) {
return false;
}
l ++;
r --;
}
return true;
}
}
速度最快:
class Solution {
int[][] f;
List<List<String>> ret = new ArrayList<List<String>>();
List<String> ans = new ArrayList<String>();
int n;
public List<List<String>> partition(String s) {
n = s.length();
f = new int[n][n];
dfs(s, 0);
return ret;
}
public void dfs(String s, int i) {
if (i == n) {
ret.add(new ArrayList<String>(ans));
return;
}
for (int j = i; j < n; ++j) {
if (isPalindrome(s, i, j) == 1) {
ans.add(s.substring(i, j + 1));
dfs(s, j + 1);
ans.remove(ans.size() - 1);
}
}
}
//速度快主要表现在判断回文串这部分
// 记忆化搜索中,f[i][j] = 0 表示未搜索,1 表示是回文串,-1 表示不是回文串
public int isPalindrome(String s, int i, int j) {
if (f[i][j] != 0) {
return f[i][j];
}
if (i >= j) {
f[i][j] = 1;
} else if (s.charAt(i) == s.charAt(j)) {
f[i][j] = isPalindrome(s, i + 1, j - 1);
} else {
f[i][j] = -1;
}
return f[i][j];
}
}