题目
Given a string s, partition s such that every substring of the partition is a palindrome.
Return the minimum cuts needed for a palindrome partitioning of s.
For example, given s =“aab”,
Return1since the palindrome partitioning[“aa”,“b”]could be produced using 1 cut.
思路
这属于动态规划的问题,关键是写出状态转移方程。
- 解法一:dp[i][j]表示i->j的最小切数,则状态转移方程为dp[i][j]=min{dp[i][p]+dp[p+1][j]} + 1
- 解法二:dp[i]表示0->i的最小切数,则状态转移方程为dp[i] = min{dp[i, dp[j-1]+1}, 其中j<=i.且j->i之间的字符串是回文。
java实现
public static int solution1(String str) {
int len = str.length();
int[][] dp = new int[len+1][len+1];
for (int t = 0; t <= len; t++) {
for (int i = 0, j = t; j <= len; i++, j++) {
dp[i][j] = s1CompCut(i, j, str, dp);
}
}
return dp[0][len];
}
public static int s1CompCut(int i, int j, String str, int[][] dp) {
String subStr = str.substring(i, j);
if (isPalidrome(subStr)) {
return 0;
}
int min = str.length();
for (int p = i; p < j; p++) {
min = Math.min(dp[i][p] + dp[p+1][j] + 1, min);
}
return min;
}
// 判断是否是回文
public static boolean isPalidrome(String str) {
return new StringBuffer(str).reverse().toString().equals(str);
}
public static int solution2(String str) {
int len = str.length();
int [] dp = new int[len+1]; // dp[i]表示0-》i之间的切点数,包括i吧
for (int i = 0; i < len; i++) {
dp[i] = isPalidrome(str.substring(0, i+1)) ? 0 : i; // 初始化,dp[i]最多的切点数就是i个,如果本身是回文,就初始为0
if (dp[i] == 0) {
continue;
}
for (int j = 1; j <= i; j++) {
if (isPalidrome(str.substring(j, i+1))) {
dp[i] = Math.min(dp[i], dp[j-1] + 1);
} else {
dp[i] = Math.min(dp[i], dp[j-1] + i - j + 1);
}
}
}
return dp[len-1];
}
// 判断是否是回文
public static boolean isPalidrome(String str) {
return new StringBuffer(str).reverse().toString().equals(str);
}
总结
关键就是找到状态转移方程以及初始状态。