dp[i]为字符串的前i个字符至少需要切几刀
,则对于前i个字符串从前往后遍历每个位置j,若j+1~i
位置为回文的,则进行判断min(dp[j]+1,dp[i])
,则可得到状态转移方程:dp[i]=min(dp[j]+1,dp[i])
/**
* 状态dp[i]:表示前缀子串s[0:i]分割成若干个回文子串所需要的最小分割次数
* 思考的方向是:
* 大问题的最优解是怎么由最小问题的最优解得到的?
*
* 即dp[i]如何与dp[i-1]、dp[i-2]、dp[i-3]、 。。。。。dp[0]建立联系的
*
* 比较容易想到的是:如果s[0:i]本身就是一个回文串,那么不用分割,。即dp[i]=0,这首先可以判断,否则需要遍历
*
* 接下来枚举所有可能分割的位置:即如果s[0:i]本身不是一个回文串,就尝试分割,枚举分割边界j
* 如果s[j+1,i]不是回文串,尝试下一个分割边界
* 如果s[j+1,i]是回文串,则dp[i]就是在dp[j[的基础上多挑一个分割
*
* 也是枚举j所有可能的位置,取所有dp[j]中最小的再加1,就是dp[i]
*
* 状态转移方唱
*
* dp[i]=Math.min(dp[j]+1,dp[i]) //其中 i ,j为字符串的索引位置 并且有j<iand j+1~i为回文字符
*
* 初始状态:单个字符一定是回文串,因此dp[0]=0
*
* 思考输出:状态转移方程可以得到,并且状态就是题目问的 dp[lem-1]
*
package BDyNamicProgramming;
import DString.Problem3;
/**
* @Author Zhou jian
* @Date 2020 ${month} 2020/4/24 0024 16:48
*/
public class Problem132 {
/**
* 状态dp[i]:表示前缀子串s[0:i]分割成若干个回文子串所需要的最小分割次数
* 思考的方向是:
* 大问题的最优解是怎么由最小问题的最优解得到的?
*
* 即dp[i]如何与dp[i-1]、dp[i-2]、dp[i-3]、 。。。。。dp[0]建立联系的
*
* 比较容易想到的是:如果s[0:i]本身就是一个回文串,那么不用分割,。即dp[i]=0,这首先可以判断,否则需要遍历
*
* 接下来枚举所有可能分割的位置:即如果s[0:i]本身不是一个回文串,就尝试分割,枚举分割边界j
* 如果s[j+1,i]不是回文串,尝试下一个分割边界
* 如果s[j+1,i]是回文串,则dp[i]就是在dp[j[的基础上多挑一个分割
*
* 也是枚举j所有可能的位置,取所有dp[j]中最小的再加1,就是dp[i]
*
* 状态转移方唱
*
* dp[i]=Math.min(dp[j]+1,dp[i]) //其中 i ,j为字符串的索引位置 并且有j<iand j+1~i为回文字符
*
* 初始状态:单个字符一定是回文串,因此dp[0]=0
*
* 思考输出:状态转移方程可以得到,并且状态就是题目问的 dp[lem-1]
*
*
* @param s
* @return
*/
public int minCut(String s) {
if(s.length()==0||s.length()==1) return 0;
int[] dp = new int[s.length()];
for (int i = 0; i < s.length(); i++) {
dp[i] = i;
}
for(int i=1;i<s.length();i++){
//如果从i到当前是回文的则不用加
if (checkPalindrome(s, 0, i)) {
dp[i] = 0;
continue;
}
for(int j=0;j<i;j++){
//判断从j+1到i是否为回文子串
boolean flag = checkPalindrome(s,j+1,i);
if(flag){//若为回文子串,则判断dp[i]是否需要更新
dp[i]=Math.min(dp[i],dp[j]+1);
}
}
}
return dp[s.length()-1];
}
/*
判断是否为回文子串
*/
private boolean checkPalindrome(String s, int left, int right) {
while (left < right) {
if (s.charAt(left) != s.charAt(right)) {
return false;
}
left++;
right--;
}
return true;
}
public static void main(String[] args) {
String s = "aab";
Problem132 problem132 = new Problem132();
int size = problem132.minCut(s);
System.out.println(size);
}
}