其他分享
首页 > 其他分享> > LeetCode5. 最长回文子串

LeetCode5. 最长回文子串

作者:互联网

题目

分析

Manacher 算法算法比较复杂,不考虑,我们只学习中心扩散算法和DP

法一、采用中心扩散法

也就是枚举每个点,找到最长的回文串。回文串分为两种:奇数和偶数长度的回文串。其中奇数的串是关于中心对称的,偶数的串是左右相同。

因为要求最长的回文子串,但是我们并不清楚最长的回文子串的长度是奇数还是偶数,所以要覆盖两种情况。

题目中的数据长度范围都是1000比较小,这种方法的时间复杂度是O(n2)的所以可以通过。

法二、采用动态规划DP

https://leetcode-cn.com/problems/longest-palindromic-substring/solution/cdong-tai-gui-hua-by-ye-ao-nai-wo-he-1-tpdy/

代码

法一、中心扩散法

 1 class Solution {
 2 public:
 3     string longestPalindrome(string s) {
 4         string res;
 5         
 6         //枚举每个中心点
 7         for(int i = 0;i < s.size();i++){
 8             
 9             //假设回文串的长度为奇数
10             int l = i - 1,r = i + 1;
11             while( l >= 0 && r < s.size() && s[l] == s[r]){
12                 l--,r++;
13             }
14             if(res.size() < (r -1) - (l + 1) + 1) res = s.substr(l+1,r-l-1);
15 
16             //假设回文串的长度为偶数
17             l = i,r = i + 1;
18             while(l >= 0 && r <s.size() && s[l] == s[r]){
19                 l--,r++;
20             }
21             if(res.size() < (r -1) - (l + 1) + 1) res = s.substr(l+1,r-l-1);
22         }
23 
24         return res;
25     }
26 };

法二、动态规划

 1 class Solution {
 2 public:
 3     string longestPalindrome(string s) {
 4         if(s.size() < 2) return s;
 5 
 6         int max_len = 1;
 7         int start = 0;
 8         //二位dp数组,用来存放[i,j]是否是回文子串,如果是就为1,否则为0
 9         vector<vector<int>>dp(s.size(),vector<int>(s.size()));
10 
11         //dp数组初始化,单个长度的子串一定是回文子串
12         for(int i = 0;i < s.size();i++){
13             dp[i][i] = 1;
14         }
15 
16         for(int len = 2;len <= s.size();len++){
17             for(int i = 0;i < s.size();i++){
18 
19                 int j = len + i -1; 
20                 //j为终点的下标,其中len = j - i + 1
21 
22 
23                 if(j > s.size() - 1) break;  //j的右侧极限
24 
25                 if(s[i] != s[j]) dp[i][j] = 0;
26                 else{
27                     if(len == 2) dp[i][j] = 1; //长度为2,肯定是回文串
28                     else dp[i][j] = dp[i+1][j-1]; 
29                     //长度>2,需要看[i+1,j-1]是否为回文串
30                 }
31                 
32                 if(dp[i][j] && len > max_len){
33                     max_len = len;
34                     start = i;
35                 }
36     
37 
38 
39             }
40         }
41 
42         return s.substr(start,max_len);
43     }
44 };

 

本题不论是中心扩散法还是动态规划算法时间复杂度都为O(n2),区别在于中心扩散算法的空间复杂度为O(1),动态规划算法的空间复杂度为O(n2),要存储一个DP数组。

标签:子串,LeetCode5,int,len,回文,dp,size
来源: https://www.cnblogs.com/fresh-coder/p/15962195.html