1. 程式人生 > >LeetCode 132.Palindrome Partitioning II (分割回文串 II)

LeetCode 132.Palindrome Partitioning II (分割回文串 II)

題目描述:

給定一個字串 s,將 s 分割成一些子串,使每個子串都是迴文串。

返回符合要求的最少分割次數。

示例:

輸入: "aab"
輸出: 1
解釋: 進行一次分割就可將 s 分割成 ["aa","b"] 這樣兩個迴文子串。

AC C++ Solution:

解題思路:

isPalin[i][j] , which is whether s[i..j] forms a pal

minCuts[i], which is the minCut for s[0..i-1]

一種典型的解決方案是基於DP。這種解決方案首先構造一個二維bool陣列isPalin,以指示子串s [i..j]是否是迴文結構。要獲得這樣的陣列,我們需要O(N ^ 2)時間複雜度。此外,為了獲得最小切割,我們需要另一個數組minCuts來執行DP,minCuts [i]儲存為子串s [0..i-1]找到的最小切割。minCuts [i]被初始化為i-1,這是所需的最大切割(將字串切割成單字母字元),minCuts [0]最初設定為-1,這在s [0 .. i-1]是迴文。當我們構造isPalin陣列時,我們每次找到迴文子字串時都會更新minCuts,即如果s [i..j]是迴文,則minCuts [j + 1]將更新為當前minCuts [j]的最小值+1]和minCut [i] +1(即將s [0..j]切換為s [0,i-1]和s [i,j])

程式碼:

// DP solution
    class Solution {
    public:
        int minCut(string s) {
            const int N = s.size();
            if(N<=1) return 0;
            int i,j;
            bool isPalin[N][N];
            fill_n(&isPalin[0][0], N*N, false);
            int minCuts[N+1];
            for(i=0; i<=N; ++i) minCuts[i] = i-1;
            
            for(j=1; j<N; ++j)
            {
                for(i=j; i>=0; --i)
                {
                    if( (s[i] == s[j]) && ( ( j-i < 2 ) || isPalin[i+1][j-1] ) )
                    {
                        isPalin[i][j] = true;
                        minCuts[j+1] = min(minCuts[j+1], 1 + minCuts[i]);    
                    }
                }
            }
            return minCuts[N];
            
        }
    };