leetcode: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.

For example, given s = "aab",
Return 1 since the palindrome partitioning ["aa","b"] could be produced using 1 cut.


思路:动态规划,字符串从第一个字符开始,每在右边增加一个字符i,就判断这个字符与左边的哪些字符(如j的位置,j<=i)可以连成回文,

用flg[k] 记录0-k为止需要截断的次数,则 flg[i]= min( flg[i]=flg[j]+1, flg[i] )(str[j-i]为回文,j可能有多个,所以要用min)

下面第一提交超时:因为每次都判断str[j-i]是否是回文-isPalindrome

class Solution {
public:
     bool isPalindrome(string s,int start,int end){  
        int i=start;  
        int j=end;  
        while(i<j){  
            if(s[i++]!=s[j--])  
                return false;  
        }  
        return true;  
    }
    void setFlgVlaue(string &s,vector<int> &flg,int endIndex)
    {
        for(int i=endIndex;i>=0;i--){
            if(isPalindrome(s,i,endIndex))
                flg[endIndex] = (i== 0) ? 0 : min( flg[i-1] + 1 , flg[endIndex] );
        }
    }
    int minCut(string s) {
        int ret=0;
        if(s.size()==0)
            return ret;
        vector<int> flg(s.size(),s.size()-1);
        flg[0]=0;
        for(int i=1;i<s.size();i++){
            setFlgVlaue(s,flg,i);
            //cout<<flg[i]<<" ";
        }
        return flg[s.size()-1];
    }
};

其实,判断【i,j】是否是回文也可以用动态规划,用isPalindromeFlg[i][j] 表示 i到j是否是回文,则 

isPalindromeFlg[i][j] =    s[i]==s[j]  && isPalindromeFlg[i+1][j-1] , j-i>=2

                                         s[i]==s[j] , j-i<2

class Solution {
public:
    void setFlgVlaue(string s,vector<int> &flg,vector<vector<int>> &isPalindromeFlg,int endIndex)
    {
        for(int i=0;i<=endIndex;i++){ //有等于
            if( s[i]==s[endIndex] && ( endIndex-i<2 || isPalindromeFlg[i+1][endIndex-1] ) )
            {
                isPalindromeFlg[i][endIndex]=true;
                flg[endIndex] = (i== 0) ? 0 : min( flg[i-1] + 1 , flg[endIndex] );   
            }
        }
    }
    int minCut(string s) {
        int ret=0;
        if(s.size()==0)
            return ret;
        vector<int> flg(s.size(),s.size()-1);
        vector<vector<int>> isPalindromeFlg( s.size(),vector<int>(s.size(),false) );
        flg[0]=0;
        for(int i=1;i<s.size();i++){
            setFlgVlaue(s,flg,isPalindromeFlg,i);
            //cout<<flg[i]<<" ";
        }
        return flg[s.size()-1];
    }
};

下面代码从从后往前遍历,往前增加字符(转自

http://www.acmerblog.com/leetcode-solution-palindrome-partitioning-ii-6228.html

01 // LeetCode, Palindrome Partitioning II
02 // 时间复杂度O(n^2),空间复杂度O(n^2)
03 class Solution {
04 public:
05     int minCut(string s) {
06         const int n = s.size();
07         int f[n+1];
08         bool p[n][n];
09         fill_n(&p[0][0], n * n, false);
10         //the worst case is cutting by each char
11         for (int i = 0; i <= n; i++)
12             f[i] = n - 1 - i; // 最后一个f[n]=-1
13         for (int i = n - 1; i >= 0; i--) {
14             for (int j = i; j < n; j++) {
15                 if (s[i] == s[j] && (j - i < 2 || p[i + 1][j - 1])) {
16                     p[i][j] = true;
17                     f[i] = min(f[i], f[j + 1] + 1);
18                 }
19             }
20         }
21         return f[0];
22     }
23 };

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值