题目链接 : https://leetcode-cn.com/problems/palindrome-partitioning/
题目描述:
给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串。
返回 s 所有可能的分割方案。
示例:
输入: "aab"
输出:
[
["aa","b"],
["a","a","b"]
]
思路:
思路一: 回溯算法
思路二: 动态规划 + DFS
大家可以先看 5. 最长回文子串(题解链接)的动态规划方法, 我们用dp[j][i]
字符串从位置j
到位置i
(闭区间)是否为回文子串.
再用DFS把所有可能找到!
相关题型:132. 分割回文串 II
代码:
思路一:
class Solution:
def partition(self, s: str) -> List[List[str]]:
res = []
def helper(s, tmp):
if not s:
res.append(tmp)
for i in range(1, len(s) + 1):
if s[:i] == s[:i][::-1]:
helper(s[i:], tmp + [s[:i]])
helper(s, [])
return res
java
class Solution {
public List<List<String>> partition(String s) {
List<List<String>> res = new ArrayList<>();
backtrack(res, s, new ArrayList<String>());
return res;
}
private void backtrack(List<List<String>> res, String s, ArrayList<String> tmp) {
if (s == null || s.length() == 0) res.add(new ArrayList<>(tmp));
for (int i = 1; i <= s.length(); i++) {
if (isPalidrome(s.substring(0, i))) {
// System.out.println(s.substring(0, i));
tmp.add(s.substring(0, i));
backtrack(res, s.substring(i, s.length()), tmp);
tmp.remove(tmp.size() - 1);
}
}
}
private boolean isPalidrome(String sb) {
int left = 0;
int right = sb.length() - 1;
while (left < right) {
if (sb.charAt(left) != sb.charAt(right)) return false;
left++;
right--;
}
return true;
}
}
思路二:
class Solution:
def partition(self, s: str) -> List[List[str]]:
n = len(s)
dp = [[False] * n for _ in range(n)]
for i in range(n):
for j in range(i + 1):
if (s[i] == s[j]) and (i - j <= 2 or dp[j + 1][i - 1]):
dp[j][i] = True
#print(dp)
res = []
def helper(i, tmp):
if i == n:
res.append(tmp)
for j in range(i, n):
if dp[i][j]:
helper(j + 1, tmp + [s[i: j + 1]])
helper(0, [])
return res
java
class Solution {
public List<List<String>> partition(String s) {
List<List<String>> res = new ArrayList<>();
int n = s.length();
boolean[][] dp = new boolean[n][n];
for (int i = 0; i < n; i++) {
for (int j = 0; j <= i; j++) {
if (s.charAt(i) == s.charAt(j) && (i - j < 2 || dp[j + 1][i - 1])) dp[j][i] = true;
}
}
System.out.println(Arrays.deepToString(dp));
dfs(res, dp, 0, n, s, new ArrayList<String>());
return res;
}
private void dfs(List<List<String>> res, boolean[][] dp, int i, int n, String s, ArrayList<String> tmp) {
if (i == n) res.add(new ArrayList<>(tmp));
for (int j = i; j < n; j++) {
if (dp[i][j]) {
tmp.add(s.substring(i, j + 1));
dfs(res, dp, j + 1, n, s, tmp);
tmp.remove(tmp.size() - 1);
}
}
}
}