题目:
给定一个字符串 s
,请将 s
分割成一些子串,使每个子串都是回文串。
返回符合要求的 最少分割次数 。
示例 :
输入:s = "aab" 输出:1 解释:只需一次分割就可将 s 分割成 ["aa","b"] 这样两个回文子串。
思路:
如果要求列出切割的各个方案就适合用回溯法,之前写过。
现在只要求给出最少次数,用动态规划合适。
找状态转移方程: dp[i] = Math.min(dp[i],dp[j-1]+1);
复杂度:
时间:双重循环O(n*n)。
空间:isPal【】【】二维数组空间O(n^2)。
代码:效率比较拉胯,但是比较容易懂
public int minCut(String s) {
int n = s.length();
boolean[][] isPal = new boolean[n][n];
//判断s从下标j到i是否回文
for(int i = 0;i<n;++i){
for(int j = 0;j<=i;++j){
char ch1 = s.charAt(i);
char ch2 = s.charAt(j);
if(ch1 == ch2 && (i <= j+1 || isPal[j+1][i-1])){
isPal[j][i] = true;
}
}
}
int[] dp = new int[n];
for(int i = 0; i< n;i++){
//如果已经是回文,那dp【i】不需要加
if(isPal[0][i]) dp[i] = 0;
else{
//最差就是每个位置来一刀
dp[i] = i;
for(int j = 1;j<=i;j++){
if(isPal[j][i]){
//这一句是关键
//此时分割次数就是从0割到j-1再加一,要在j-1和j之间再割一次
dp[i] = Math.min(dp[i],dp[j-1]+1);
}
}
}
}
return dp[n-1];
}