
题目解释的特别清楚了,不过还有个,因为只有一个字母也叫回文串,那么其实所有的字母都会被使用到
那么要不重复的遍历一遍字符串的所有子串,并且要记录下每个子串,递归回溯就很适合
不过这样每次递归到一个子串,就去判断他是否为回文串,那么时间复杂度肯定要高到天上了,
而其实对于回文串,有 如果 [l ,r] 是一个回文串 那么他们的 [l + 1, r - 1] 也肯定是一个回文串, 对于单个字符 会发现 l + 1 > r - 1 那么这种特殊情况可以直接处理为 是回文串
那么就可以发现一个式子 dp[i][j] = s[i] == s[j] && dp[i + 1][j -1]
我靠这不是动态规划吗, 没错 可是使用动态规划来预处理字符串来将所有的回文串记录到dp表中 这样O(1) 的复杂度下就能判断是否为回文串了
所以这题解法式 动态规划预处理 + 递归回溯遍历所有子字符串
java
List<List<String>> ans = new ArrayList<>();
List<String> path = new ArrayList<>();
boolean[][] dp;
public List<List<String>>partition(String s) {
int n = s.length();
dp = new boolean[n][n];
for(int i = 0; i < n; i++){
Arrays.fill(dp[i], true);
}
Set<String> set = new HashSet<>();
// 预处理 从下向上 左往右 相同的位置因为l+1会越界,就不取反正都为true
for(int l = n - 1; l >= 0; l--){
for(int r = l + 1; r < n; r++){
dp[l][r] = s.charAt(l) == s.charAt(r) && dp[l + 1][r - 1];
}
}
// 递归所有可能 然后找打可能的组合 用dp来判断是否是回文串
dfs(s, 0);
return ans;
}
void dfs(String ss, int l){
if(l == ss.length()){
ans.add(new ArrayList(path));
return;
}
for(int r = l; r < ss.length(); r++){
if(dp[l][r]){
path.add(ss.substring(l, r + 1));
dfs(ss, r + 1);
path.remove(path.size() - 1);
}
}
}
还是挺有意思居然用了俩种算法