码迷,mamicode.com
首页 > 其他好文 > 详细

5-最长回文子串

时间:2020-03-10 14:17:17      阅读:42      评论:0      收藏:0      [点我收藏+]

标签:span   一个   单个字符   就是   code   view   检索   pre   构造   

1、动态规划

首先单个字符就是一个回文子串,如果两个字符都相同就是一个回文子串,三个字符是在一个字符的左右两边加上相同字符而成的回文子串,四个字符是两个字符左右两边加上相同字符形成的回文子串。

不妨以单个字符和双个字符为初始条件去构造动态方程:

dp[i][i]=1;//单个字符

dp[i][i+1]=1;  (s[i]=s[i+1])

技术图片
 1 class Solution {
 2 public:
 3     string longestPalindrome(string s) {
 4         int len=s.size();
 5         if(len==0||len==1)
 6             return s;
 7         int start=0;//回文串起始位置
 8         int max=1;//回文串最大长度
 9         vector<vector<int>>  dp(len,vector<int>(len));//定义二维动态数组
10         for(int i=0;i<len;i++)//初始化状态
11         {
12             dp[i][i]=1;
13             if(i<len-1&&s[i]==s[i+1])
14             {
15                 dp[i][i+1]=1;
16                 max=2;
17                 start=i;
18             }
19         }
20         for(int l=3;l<=len;l++)//l表示检索的子串长度,等于3表示先检索长度为3的子串
21         {
22             for(int i=0;i+l-1<len;i++)
23             {
24                 int j=l+i-1;//终止字符位置
25                 if(s[i]==s[j]&&dp[i+1][j-1]==1)//状态转移
26                 {
27                     dp[i][j]=1;
28                     start=i;
29                     max=l;
30                 }
31             }
32         }
33         return s.substr(start,max);//获取最长回文子串
34     }
35 };
View Code

2、中心扩展法

思路就是回文子串可以从他的中心进行扩展,并且只有 2n-1 个这样的中心(一个元素为中心的情况有 n 个,两个元素为中心的情况有 n-1 个)

假如回文的中心为 双数,例如 abba,那么可以划分为 ab bb ba,对于n长度的字符串,这样的划分有 n-1 种。

假为回文的中心为 单数,例如 abcd, 那么可以划分为 a b c d, 对于n长度的字符串,这样的划分有 n 种。

对于 n 长度的字符串,我们其实不知道它的回文串中心倒底是单数还是双数,所以我们要对这两种情况都做遍历,也就是 n+(n-1) = 2n - 1,所以时间复杂度为 O(n)。

当中心确定后,我们要围绕这个中心来扩展回文,那么最长的回文可能是整个字符串,所以时间复杂度为 O(n)。

所以总时间复杂度为 O(n^2)

技术图片
 1     string longestPalindrome(string s) 
 2     {
 3         if (s.length() < 1)
 4         {
 5             return "";
 6         }
 7         int start = 0, end = 0;
 8         for (int i = 0; i < s.length(); i++)
 9         {
10             int len1 = expandAroundCenter(s, i, i);//一个元素为中心
11             int len2 = expandAroundCenter(s, i, i + 1);//两个元素为中心
12             int len = max(len1, len2);
13             if (len > end - start)
14             {
15                 start = i - (len - 1) / 2;
16                 end = i + len / 2;
17             }
18         }
19         return s.substr(start, end - start + 1);
20     }
21 
22     int expandAroundCenter(string s, int left, int right)
23     {
24         int L = left, R = right;
25         while (L >= 0 && R < s.length() && s[L] == s[R])
26         {// 计算以left和right为中心的回文串长度
27             L--;
28             R++;
29         }
30         return R - L - 1;
31     }
View Code

 

5-最长回文子串

标签:span   一个   单个字符   就是   code   view   检索   pre   构造   

原文地址:https://www.cnblogs.com/nxnslc-blog/p/12454987.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!