132-分隔字符串，得到回文II

Description
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.

class Solution {
public int minCut(String s) {
int len = s.length();

Map<String, Integer> memo = new HashMap();
//注意这里需要先放入空串,其对应切分数为0
memo.put("", 0);

return dfs(s, memo) - 1;
}
public int dfs(String s, Map<String, Integer> memo){
if(memo.containsKey(s))    return memo.get(s);

int min = s.length();
for(int i = s.length() - 1;i >= 0;i--){
if(isPalindrome(s, 0, i)){
min = Math.min(min, 1 + dfs(s.substring(i + 1), memo));
}
//注意这里,若得到1或者2，退出循环，因为1或者2已经是最小的结果了
if(min == 1 || min == 2)    break;
}
memo.put(s, min);

return min;
}
//判断是否为回文
public boolean isPalindrome(String s, int left, int right){
while(left < right){
if(s.charAt(left) != s.charAt(right))   return false;
left++;
right--;
}

return true;
}
}

class Solution {
public int minCut(String s) {
int len = s.length();

int[] dp = new int[len];
//回文bool数组,若pal[i][j] = true,表示s.substring(i, j + 1)为回文
boolean[][] pal =  new boolean[len][len];

for(int i = len - 1;i >= 0;i--){
dp[i] = len - i - 1;
for(int j = i;j < len;j++){
//判断s.substring(i, j + 1)是否为回文
if(s.charAt(i) == s.charAt(j) && (j - i < 2 || pal[i + 1][j - 1])){
//若是回文，将pal[i][j]标为true
pal[i][j] = true;
//若j == len - 1,说明s.substring(i, len)为回文，直接为0
if(j == len - 1)    dp[i] = 0;
else                dp[i] = Math.min(dp[i], dp[j + 1] + 1);
}
}
}

return dp[0];
}
}

/*
.......aba...
|<-X->| ^
|<---Y-->|

*/
class Solution {
public int minCut(String s) {
if (s == null || s.length() < 2) return 0 ;

int N = s.length() ;
int C[] = new int[N] ;
Arrays.fill(C, N-1) ;

char[] str = s.toCharArray() ;
for (int l = 0 ; l < N ; ++ l) {
//奇数长度的回文串
updateCutForPalindrome(str, l, l, C, N) ;
//偶数长度的回文串
updateCutForPalindrome(str, l, l+1, C, N) ;
}

return C[N-1] ;
}

void updateCutForPalindrome(char[] str, int s, int e, int[] C, int N){
while ( s >= 0 && e < N && str[s] == str[e]) {
C[e] = Math.min(C[e], (s-1 >= 0 ? C[s-1] : -1) + 1) ;
++ e ;
-- s ;
}
}
}