[Leetcode] palindrome partition 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.
For example, given s ="aab",
Return1since the palindrome partitioning["aa","b"]could be produced using 1 cut.
题意:给定字符串s,分割s,使其每个子串都是回文串,至少需要切几下。
思路:动态规划。维护数组dp[ ] ,dp[ i ]代表(0 ,i)最小的回文切割。遍历字符串,当子串s.substr(0,i+1)(包括 i 位置的字符)是回文时,dp[i]=0,即表示不用切割,若不是回文,则令dp[ i ]=i ,表示至少要切 i 刀(有i+1个字符)。对于任意大于1的 i,如果s.substr(j,i+1)(j<=i,即遍历i之前的每个子串)
是回文时,转移方程:dp[i]=min(dp[i],dp[j-1]+1),因为若是,则只要增加一刀,就可以分为两个子串了;若不是,则取dp[i]=min(dp[i],dp[i-1]+1),因为,为回文串时,状态转移方程中j-1>=0,说明,首字符没有考虑,若出现如“efe”的情况时,dp[i] 的值就小于dp[ i-1 ]+1。代码如下:
1 class Solution { 2 public: 3 int minCut(string s) 4 { 5 int len=s.size(); 6 if(len<2) return 0; 7 8 vector<int> dp(len,0); 9 10 for(int i=1;i<len;i++) 11 { 12 if( !isPalin(s,0,i)) 13 dp[i]=i; 14 } 15 16 for(int i=1;i<len;++i) 17 { 18 for(int j=1;j<i;j++) 19 { 20 if(isPalin(s,j,i)) 21 dp[i]=min(dp[i],dp[j-1]+1); 22 else 23 dp[i]=min(dp[i],dp[i-1]+1); 24 } 25 } 26 return dp[len-1]; 27 } 28 29 bool isPalin(string &s,int l,int r) 30 { 31 int i=l,j=r; 32 while(i<j) 33 { 34 if(s[i] !=s[j]) 35 return false; 36 i++; 37 j--; 38 } 39 return true; 40 } 41 };
博友Grandyang,使用DP简化了每次第(j,i+1)之间的是否为回文串的判断。