leetcode131 分割回文串

先用动态规划搞出来每段字符是否是回文子串。之后写一个函数,不断从头开始向后走,并且判断中间的字符是否为回文子串,如果是,则递归,寻找剩下字符串所有的分割形式,返回之后就将返回的所有字符串组合加上本身这个回文子串,就完成了任务。但是执行出来效果较差,可能是递归的问题,但是逻辑算是比较清晰的,贴代码。

 1 class Solution {
 2 public:
 3     vector<vector<string>> partition(string s) 
 4     {
 5         vector<vector<string>> res;
 6         int n = s.size();
 7         vector<vector<bool>> dp(n,vector<bool>(n,false));
 8         for(int l = 1 ; l <= n ; l++)
 9         {
10             for(int j = 0 ; j+l-1 < n ; j++)
11             {
12                 if(l == 1)
13                 dp[j][j+l-1] = true;
14                 else if(l == 2)
15                 dp[j][j+l-1] = (s[j]==s[j+l-1]);
16                 else
17                 dp[j][j+l-1] = (dp[j+1][j+l-2] && s[j]==s[j+l-1]);
18             }
19         }
20         return search(0,n-1,dp,s);
21     }
22     vector<vector<string>> search(int m,int n,vector<vector<bool>>& dp,string& s)
23     {
24         vector<vector<string>> res;
25         if(m == n)
26         {
27             vector<string> res_temp;
28             res_temp.push_back(s.substr(m));
29             res.push_back(res_temp);
30         }
31         else
32         {
33             for(int i = m ; i < n ; i++)
34             {
35                 if(dp[m][i])
36                 {
37                     string res_temp;
38                     res_temp = s.substr(m,i-m+1);
39                     vector<vector<string>> res_temp_1 = search(i+1,n,dp,s);
40                     for(auto temp:res_temp_1)
41                     {
42                         temp.insert(temp.begin(),res_temp);
43                         res.push_back(temp);
44                     }
45                 }
46             }
47             if(dp[m][n])
48             {
49                 vector<string> res_temp;
50                 res_temp.push_back(s.substr(m,n-m+1));
51                 res.push_back(res_temp);
52             }           
53         }
54         return res;         
55     }
56 };

看了下官方的题解,对于全局变量的应用更加巧妙,并且有回溯的想法,相当于如果搜索到了最后一个字符,就代表我已经完成了一次分割,当前res数组中的内容就是一种分割的形式,将该分割上传至总答案数组中,之后就进行到递归的回溯环节,在回溯的时候,会删除当前往res中添加的字符串,继续往下搜索,也就是寻找有没有其他的分割形式,直到完成全部回溯。贴下修改的代码。

 1 class Solution {
 2 public:
 3     vector<vector<string>> ret;
 4     vector<string> res;
 5     vector<vector<string>> partition(string s) 
 6     {
 7         int n = s.size();
 8         vector<vector<bool>> dp(n,vector<bool>(n,false));
 9         for(int l = 1 ; l <= n ; l++)
10         {
11             for(int j = 0 ; j+l-1 < n ; j++)
12             {
13                 if(l == 1)
14                 dp[j][j+l-1] = true;
15                 else if(l == 2)
16                 dp[j][j+l-1] = (s[j]==s[j+l-1]);
17                 else
18                 dp[j][j+l-1] = (dp[j+1][j+l-2] && s[j]==s[j+l-1]);
19             }
20         }
21         search(0,n,dp,s);
22         return ret;
23     }
24     void search(int m,int n,vector<vector<bool>>& dp,string& s)
25     {
26         if(m == n)
27         {
28             ret.push_back(res);
29             return;
30         }
31         else
32         {
33             for(int i = m ; i < n ; i++)
34             {
35                 if(dp[m][i])
36                 {
37                     res.push_back(s.substr(m,i-m+1));
38                     search(i+1,n,dp,s);
39                     res.pop_back();
40                 }
41             }       
42         }       
43     }
44 };

在效率上确实有一定的提升。

posted @ 2021-09-17 10:03  zhaohhhh  阅读(29)  评论(0)    收藏  举报