1. 程式人生 > >LeetCode Palindrome Partitioning II

LeetCode Palindrome Partitioning II

這道題與相似。用DP來做,需要保留的歷史資訊就是到當前點能分成幾塊Palindrome, 用一個int陣列res保留。每次更新res[i+1], 比較i+1和res[j]+1大小,取小的。因為單個letter肯定是palindrome, 所以肯定會被字典拆開,但[j...i]這一段可能是一個palindrome, 所以數量應更新成res[j]+1與i+1中較小的一個。

用二維boolean陣列儲存字典,boolean[i][j]表示從i到j這一段是否是迴文。

Note:1. helper當中判斷使用dict[i+1][j-1]之前需先判定i,j 是否out of index了,這類問題都是如此,需先判斷index有沒有out of bound.

2. minCut中,雙層loop的內層loop, j 是由 0 到 i, 判斷isDic[j][i]是否為true.

AC Java:

public class Solution {
    public int minCut(String s) {
        if(s == null || s.length() == 0){
            return 0;
        }
        int len = s.length();
        boolean[][] isDic = helper(s);
        int [] res = new int[len+1];
        res[0] = 0;
        for(int i = 0; i < len; i++){
            res[i+1] = i+1;
            for(int j = 0; j <= i; j++){        //error
                if(isDic[j][i]){
                    res[i+1] = Math.min(res[i+1],res[j]+1);
                }
            }
        }
        return res[len] - 1;
    }
    
    //helper function builds dictionary
    private boolean[][] helper(String s){
        int len = s.length();
        boolean[][] dict = new boolean[len][len];
        for(int i = len-1; i>=0; i--){
            for(int j = i; j < len; j++){
                if(s.charAt(i) == s.charAt(j) && ((j-i)<2 || dict[i+1][j-1] )){     //error
                    dict[i][j] = true;
                }
            }
        }
        return dict;
    }
}