[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)之间的是否为回文串的判断。

原文地址:https://www.cnblogs.com/love-yh/p/7115251.html