LeetCode 5. 最长回文子串 Longest Palindromic Substring
Posted 陈皮
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode 5. 最长回文子串 Longest Palindromic Substring相关的知识,希望对你有一定的参考价值。
题目:
给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为1000。
示例 1:
输入: "babad" 输出: "bab" 注意: "aba"也是一个有效答案。
示例 2:
输入: "cbbd" 输出: "bb"
解法一
遍历字符串,以每个字母为中心,向两边扩散查找,记录当前最长的回文子串的长度和起始位置、结尾位置。时间复杂度O(n^2)
注意:
①当剩下的字符串长度小于当前maxlen的一半时,说明遍历剩下的字符也找不到>maxlen的回文子串了,故直接结束。
②遍历的时候需要过滤掉连续相同的字母,因为连续相同的字母一定回文,没必要再一个个遍历。
1 //遍历判断
2 string longestPalindrome(string s) {
3 if(s.length() <= 1) return s;
4 int start=0,maxlen=1;
5 for(int i = 0;i<s.length();){
6 if(s.length()-i < maxlen/2)break;//当剩下的字符串长度小于当前maxlen的一半时,说明遍历剩下的字符也找不到>maxlen的回文子串了,故直接结束。
7 int left=i,right=i;
8 while(s[right] == s[right+1] && right<s.length()-1){//过滤相同字母
9 ++right;
10 }
11 while(s[left-1] == s[right+1] && left > 0 && right < s.length()-1){
12 --left;++right;
13 }
14 if(maxlen < right-left+1){
15 maxlen = right-left+1;
16 start = left;
17 }
18 i = right+1;
19 }
20 return s.substr(start,maxlen);
21 }
解法二
动态规划,时间复杂度O(n^2).
利用动态规划解题,i,j 分别表示子串的起始和结束位置,动态规划矩阵dp[i][j]表示以是第i个元素开始,以第j个元素结束的子串是否为回文串,是就记为1,否则记为0.
dp[i][j]的状态与dp[i+1][j-1]相关,及当dp[i+1][j-1]且s[i] == s[j]的时候,我们就可以判定dp[i][j] = 1;
dp[i][j] = (s[i] == s[j]) && (dp[i+1][j-1] || j-i<=1);
//动态规划
string dp_longestPalindrome(string s) {
int size = s.length();
if(size <= 1) return s;
int left=0,right=0,maxlen=1;
int dp[size][size]={0};
for(int i = 0;i < size;++i){
for(int j = i-1;j >= 0 ;--j){
if(s[i]==s[j] && (i-j<=1 || dp[j+1][i-1])) dp[i][j] = 1;
if(dp[j][i] && maxlen < i-j+1){
maxlen = i-j+1;
right = i;
left = j;
}
}
dp[i][i] = 1;
}
return s.substr(left,right-left+1);
}
解法三
马拉车算法Manacher\'s Algorithm, 时间复杂度O(n).
PS:这个算法我还没看太懂,后续再回来补充。
关于这个算法推荐学习博客:https://www.cnblogs.com/mini-coconut/p/9074315.html
以上是关于LeetCode 5. 最长回文子串 Longest Palindromic Substring的主要内容,如果未能解决你的问题,请参考以下文章