leetcode 5. Longest Palindromic Substring
题目:Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000.
题目解析:做题一定不要陷入惯性思维,要注重审题,从题目出发。不要看到题以为跟之前的题类似就想也不想就套之前的做法。可能题目稍微一变就要gg。要么是做错要么是简单的问题用了复杂的办法; 就比如这道题跟Longest palindromic subsequence类似,然后我就在这道题用了同样的解法,果然gg了。往事不堪回首。。。。。
①:判断最长的回文子串,暴力是遍历所有子串,时间复杂度O(N^2);
判断长度为l,从i开始的子串是不是回文字符串:当且仅当dp[l][i] = (s[i] == s[i+l-1] && dp[l-2][i+1])
class Solution {
public:
string longestPalindrome(string s)
{
int len = s.size() ;
if(len == 0) return "" ;
vector<vector<int>> dp(len + 1 , vector<int>(len , 0));
for(int i = 0 ; i < len ; i++)
{
dp[0][i] = 1 ;
dp[1][i] = 1 ;
}
string res = string(1 ,s[0]) ;
for(int l = 2 ; l <= len ; l++)
{
for(int i = 0 ; i + l <= len; i++)
{
dp[l][i] = (s[i] == s[i+l-1] && dp[l-2][i+1]) ;
if(dp[l][i] && l > res.size()) res = s.substr(i , l) ;
}
}
return res ;
}
};
优化:其实可以看出当dp[l][i]不是回文字符串时,dp[l+1][i-1]....就不可能是回文字符串了。可以省略那些字符串的判断,减小时间复杂度。所以可以遍历i,从i的两边遍历以i为中心的最长回文字符串是多少?
class Solution {
public:
string longestPalindrome(string s)
{
int len = s.size() ;
int pos = 0 ;
int maxl = 0 ;
string res = "" ;
for(int i = 0 ; i < len ; i++)
{
//判断以i为中心的最长回文串,注意这回文串长度为奇数
int l = i , r = i ;
while(l > 0 && r < len - 1 && s[l-1] == s[r + 1])
{
l-- ;
r++ ;
}
if(r - l + 1 > res.size()) res = s.substr(l , r - l + 1) ;
if(i == len - 1 || s[i] != s[i+1]) continue ;
//还要判断偶数长度的回文字符串
l = i ;
r = i + 1 ;
while(l > 0 && r < len - 1 && s[l-1] == s[r+1])
{
l-- ;
r++ ;
}
if(r - l + 1 > res.size()) res = s.substr(l , r - l + 1) ;
}
return res ;
}
};
进一步优化:这是判断偶数字符串的时候想到的,当从i开始遍历的时候,如果[i,j]是一串相同子串,可以从这一串相同子串的两边开始遍历,i可以跳到j+1.因为i为[i+1,j]时,其最长回文字符串的长度不超过j-i+1;
class Solution {
public:
string longestPalindrome(string s)
{
int len = s.size() ;
int pos = 0 ;
int maxl = 0 ;
string res = "" ;
while(pos < len)
{
if((len - pos) * 2 <= maxl) break ;
int l = pos , r = pos ;
while(r < len - 1 && s[r+1] == s[r]) r++ ;
pos = r + 1 ;
while(l > 0 && r < len - 1 && s[l-1] == s[r+1])
{
l-- ;
r++ ;
}
if(r - l + 1 > maxl)
{
maxl = r - l + 1 ;
res = s.substr(l , r - l + 1) ;
}
}
return res ;
}
};
浙公网安备 33010602011771号