1. 程式人生 > >動態規劃——Palindrome Partitioning II

動態規劃——Palindrome Partitioning II

Palindrome Partitioning II 這個題意思挺好理解,提供一個字串s,將s分割成多個子串,這些字串都是迴文,要求輸出分割的最小次數。 Example:
Input: "aab"
Output: 1
Explanation: The palindrome partitioning ["aa","b"] could be produced using 1 cut. 狀態:這個題的狀態也非常好理解,dp[i]表示將s[0..i]分割成迴文子串的最小分割次數。然後不急於尋找狀態轉移方程,我們先要明確如何用程式碼判斷一個字串的某個部分是不是迴文,其實也很好理解啊,咱們可以分塊來理解,畢竟這是個演算法題,不可能用常規的那種遍歷一半的方式來判斷。首先對於這個字串的某個子串s[j..i](j<=i),滿足它是迴文的條件兩條(1)s[j]==s[i]  (2)  只確定兩端的兩個字元還不夠,當這個子串的長度小於4或者去掉兩端的相同字元後還是迴文即可。現在我們除了遞推陣列dp,再定義一個記錄陣列pa[j][i],如果s[j..i]是迴文,則pa[j][i] = 1,否則為0。有了這兩個條件,我們就可以總結狀態轉移方程了:
dp[i] = min(dp[j-1]+1),當0<j<=i時,並且s[j..i]是迴文時
dp[i] = 0 ,當j=0,並且s[j..i]是迴文時
在具體的dp陣列遞推運算過程中,需要這兩個分支,同時會更新pa[j][i]的值便於後面的過程中迴文條件的判斷。  
 1
public int minCut(String s) { 2 int slen = s.length(); 3 int[][]pa = new int[slen][slen]; 4 int[]dp = new int[slen]; 5 for(int i = 0;i<slen;i++) 6 dp[i] = i; 7 for(int i = 0;i<slen;i++) 8 Arrays.fill(pa[i],0); 9 for
(int i = 1;i<slen;i++) { 10 for(int j = 0;j<=i;j++) { 11 if(s.charAt(j)==s.charAt(i)&&((i-j<2)||pa[j+1][i-1]==1)) { 12 pa[j][i] = 1; 13 if(j!=0)dp[i] = Math.min(dp[i],dp[j-1]+1); 14 else dp[i] = 0;
15 } 16 } 17 } 18 return dp[slen-1]; 19 }