给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串。
返回符合要求的最少分割次数。
示例:
输入: "aab"
输出: 1
解释: 进行一次分割就可将 s 分割成 ["aa","b"] 这样两个回文子串。
思路:
从后往前处理:
- boolean[][] f,f[i][j]表示s[i~j]是否为回文串
- int[] min, min[i]表示s[i~n-1]最少需要切几次
- 初始时,min[i] = 1 + min[i+1]
- s[i~n-2]中,如果存在j,f[i][j]为true,且min[i] > 1 + min[j+1],min[i] = 1 + min[j+1]
Java代码:
public int minCut(String s) {
int len = s.length();
int[] min = new int[len];
if (0 < len) {
/**
* boolean[][] f,f[i][j]表示s[i~j]是否为回文串
* int[] min, min[i]表示s[i~n-1]最少需要切几次
*/
boolean[][] f = new boolean[len][len];
for (int i = 0; i < len; i++)
f[i][i] = true;
for (int i = len-1; i >= 0; i--) {
for (int j = i; j < len; j++) {
if (j == i) {
f[i][j] = true;
continue;
}
if (j - 1 == i) {
f[i][j] = s.charAt(i) == s.charAt(j);
continue;
}
f[i][j] = f[i+1][j-1] && s.charAt(i) == s.charAt(j);
}
if (f[i][len-1]) {
min[i] = 0;
} else {
min[i] = 1 + min[i+1];
for (int k = i; k < len-1; k++) {
min[i] = Math.min(min[i], f[i][k] ? 1 + min[k+1] : min[i]);
}
}
}
}
return min[0];
}