132. Palindrome Partitioning II

来源:互联网 发布:python 2.7不支持中文 编辑:程序博客网 时间:2024/05/16 02:24

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.

我的第一想法是借助131题的回溯思想,穷举所有的可能,毫不意外这样超时了。

class Solution {public:    int min=INT_MAX;    int minCut(string s)     {        if(s.size()==0)            return 0;        vector<string>temp;        recur(s,temp);        return min-1;    }    void recur(string s,vector<string>&temp)    {        if(s.size()==0)        {            if(temp.size()<min)                min=temp.size();            return;        }        for(int i=1;i<=s.size();i++)        {            string str=s.substr(0,i);            if(!check(str))                continue;            temp.push_back(str);            recur(s.substr(i),temp);            temp.pop_back();        }    }    bool check(string a)    {        int start=0;        int end=a.size()-1;        while(start<end)        {            if(a[start]!=a[end])                return false;            start++;            end--;        }        return true;    }};

后来我看到tag提示用动态规划,状态转移方程为:如果j到i之间的子串是回文的,j的范围为0到i,那么dp[i]=min(dp[i],1+dp[j-1]),其中dp[i]的初始值为i代表i+1个元素最多切i次,当j等于0时代表整个字符串都是回文的,因此dp[i]等于0。

class Solution {public:    int minCut(string s)     {        vector<int>dp(s.size(),-1);        for(int i=0;i<s.size();i++)        {            dp[i]=i;            for(int j=i;j>=0;j--)            {                string temp=s.substr(j,i-j+1);                if(check(temp))                {                    if(j==0)                        dp[i]=0;                    else if(1+dp[j-1]<dp[i])                        dp[i]=1+dp[j-1];                }            }        }        return dp[s.size()-1];    }    bool check(string a)    {        int start=0;        int end=a.size()-1;        while(start<end)        {            if(a[start]!=a[end])                return false;            start++;            end--;        }        return true;    }};

时间复杂度是O(N^2)
但是我这样做还是超时,主要原因还是我重复判断了j到i之间是否是回文字符串,因此可以用一个二维数组来保存j到i是否是回文的,isPalin[i][j]==true代表s[i,…,j]是回文串

class Solution {public:    int minCut(string s)     {        int n=s.size();        vector<int>mincut(n,0);        vector<vector<bool> > isPalin(n, vector<bool>(n, false));        int i;        for(i=0;i<n;i++)        {            mincut[i]=i;//i+1个元素最多有i个cut            for(int j=i;j>=0;j--)            {                if(s[j]==s[i])                {                    if(i-j<=1||isPalin[j+1][i-1])                    {                        isPalin[j][i]=true;                        if(j==0)                            mincut[i]=0;                        else if(mincut[i]>(mincut[j-1]+1))                            mincut[i]=mincut[j-1]+1;                    }                }            }        }        return mincut[n-1];    }};
0 0
原创粉丝点击