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"
,
Return 1
since the palindrome partitioning ["aa","b"]
could be produced using 1 cut.
定义isPal[i][j]:
当s[i..j]为回文串时,isPal[i][j] = true;否则isPal[i][j] = false。
定义f[i]:
s[0..i]需要切割的次数。
思路:
如果isPal[0][i] = false(意味着s[0..i]不为回文串),那么至少需要将s[0..i]切割为两个part : S1 + S2。
我们人为的规定S2必须为回文串,这样我们只需要再切割S1。
假设 S1 = s[0..j] S2 = s[j + 1.. i],S1的最优切割次数我们已知(f[j]),而S2为回文串,因此总切割次数为 f[j] + 1。
class Solution {
public:
int minCut(string s) {
// Start typing your Java solution below
// DO NOT write main() function
int l = s.length();
bool isPal[l][l];
for (int i = 0; i < l; i++) {
isPal[i][i] = true;
}
for (int k = 1; k < l; k++) {
for (int i = 0; i < l - k; i++) {
int j = i + k;
isPal[i][j] = false;
if (s[i] == s[j] && i + 1 < l && j - 1 >= 0) {
if (i + 1 <= j - 1 && isPal[i + 1][j - 1] || i + 1 > j - 1) {
isPal[i][j] = true;
}
}
}
}
int f[l];
for (int i = 0; i < l; i++) {
f[i] = -1;
}
f[0] = 0;
for (int i = 1; i < l; i++) {
for (int j = 0; j <= i; j++) {
if (isPal[j][i]) {
int c = j >= 1 ? f[j - 1] + 1 : 0;
if (c < f[i] || f[i] == -1) {
f[i] = c;
if (f[i] == 0) {
break;
}
}
}
}
}
return f[l - 1];
}
};
public class Solution {
public int minCut(String s) {
// Start typing your Java solution below
// DO NOT write main() function
char[] c = s.toCharArray();
boolean[][] isPal = new boolean[c.length][c.length];
for (int i = 0; i < c.length; i++) {
isPal[i][i] = true;
}
for (int k = 1; k < c.length; k++) {
for (int i = 0; i + k < c.length; i++) {
int j = i + k;
isPal[i][j] = c[i] == c[j] && (i + 1 < j - 1 && isPal[i + 1][j - 1] || i + 1 >= j - 1);
}
}
int[] f = new int[s.length() + 1];
for (int i = 0; i <= s.length(); i++) {
f[i] = i - 1;
}
for (int i = 1; i <= s.length(); i++) {
for (int j = i; j >= 1; j--) {
if (isPal[j - 1][i - 1] && f[j - 1] + 1 < f[i]) {
f[i] = f[j - 1] + 1;
if (f[i] == 0) {
break;
}
}
}
}
return f[s.length()];
}
}