Given a string s, partition s such that every substring of the partition is a palindrome.
Return all possible palindrome partitioning of s.
For example, given s = "aab"
,
Return
[ ["aa","b"], ["a","a","b"] ]
这样的题目,首先使用O(n^2)的求回文最长回文子串的方法,如果暴力求解,就是n^3。
动态规划,可以变成O(o^2).算法如下。
s表示字符串。
dp[i][j] 为true,表示字符串从i到j是一个回文串;接着进行推理,如果s[i-1]==s[j+1]并且dp[i][j]为true,那么字符串的字串从(i-1到j+1)就是一个回文串了。所以算法是双重循环,dp[i][j] = true 的条件有 1:i==j; 2: s[i]==s[j]并且dp[i-1][j-1]为true。
通过dp求得回文串之后,可以通过深度优先搜索,因为每次dp[i][j]为true的地方对字符串进行分割,就一定是回文字串。
//8:09 class Solution { public: vector<vector<string> > res; vector<vector<string>> partition(string s) { int len = s.size(); vector<vector<bool> > dp(len,vector<bool>(len,false)); int i,j; //先求dp[i][i] 和dp[i][i+1],后面在进行迭代 for(i=0;i<len;i++){ dp[i][i] = true; if(i+1<len && s[i]==s[i+1]) { dp[i][i+1] = true; } } //求字符串的任意两个位置之间是否符合回文 for(i=1;i<len-1;i++) { for(j=0;j<len-i-1;j++) { if(dp[j+1][j+i]&&s[j]==s[j+i+1]) { dp[j][j+i+1] = true; } } } vector<string> sol; dfs(dp,sol,0,len,s); return res; } //搜索出所有的字符串分割方式 void dfs(vector<vector<bool> > &dp,vector<string> &solve,int s,int len,string &ori) { if(s==len) { res.push_back(solve); return ; } for(int i=s;i<len;i++) { //从s开始,所有后面的字串都是一个新的分割方式 if(dp[s][i]) { solve.push_back(ori.substr(s,i-s+1)); dfs(dp,solve,i+1,len,ori); solve.pop_back(); } } return ; } };
Palindrome Partitioning leetcode
原文地址:http://blog.csdn.net/nan327347465/article/details/39157263