1. 程式人生 > >DP動態規劃專題六 :LeetCode 132. Palindrome Partitioning II

DP動態規劃專題六 :LeetCode 132. Palindrome Partitioning II

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.

Example:

Input: "aab"
Output: 1
Explanation: The palindrome partitioning ["aa","b"] could be produced using 1 cut.

我們依舊沿襲palindrome partinioning的思路,可以推出這道題,但是時間複雜度比較高,為nn

len(word),第二個解法可以達到n*n

解法一:

    public int minCut(String s) {
        if (s.length() <= 1) return 0;
        int[] dp = new int[s.length()];
        for (int i = 1; i < s.length(); i++) {
            int min = Integer.MAX_VALUE;
            for (int p = 1; p <= i; p++) {
                if (isPalindrome(s.substring(p, i+1))) {
                    min= Math.min(min, dp[p-1] + 1);
                }
            }
            dp[i] = min;
            if (isPalindrome(s.substring(0, i+1))) {
                dp[i] = 0;
            }
        }
        return dp[s.length() - 1];
    }
    private boolean isPalindrome(String s) {
        if (s.length() <= 1) return true;
        int l = 0;
        int r = s.length() - 1;
        while (l < r) {
            if (s.charAt(l++) != s.charAt(r--)) {
                return false;
            }
        }
        return true;
    }

解法二:由於abbba是palindrome,因此bbb也一定是,ab不是,那麼cabc也一定不是,所以我們可以先用一個二維陣列來儲存從i到j是否是palindrome,然後ispal的時候直接看陣列就能得到答案,這樣可以減少對ispal函式的呼叫來優化時間。

    public int minCut(String s) {
        //todo: sanity checks
        if (s == null || s.length() == 0) return 0;
        //沒有長度為0 的字元: off by one
        boolean[][] dp = new boolean[s.length()][ s.length()];
        //base case
        dp[0][0] = true;
        int[] mins = new int[s.length()];
        mins[0] = 0;
        for (int i = 1; i < s.length(); i++) {
            int local = i ; //每個位置都切。 我們要求最小,所以給個大一點的值
            for (int j = 0; j <= i; j++) {
                char cj = s.charAt(j);
                char ci = s.charAt(i);
                if ( cj == ci  &&(i - j < 2 || dp[j + 1] [i - 1])){
                    dp[j][i] = true;
                    local = j == 0 ? 0 : Math.min(local, mins[j-1] + 1);
                }
            }
            mins[i] = local;
        }
        return mins[s.length() - 1];
    }