题目:
Given a string s
, return the longest palindromic substring in s
.
Example 1:
Input: s = "babad" Output: "bab" Note: "aba" is also a valid answer.
Example 2:
Input: s = "cbbd" Output: "bb"
Example 3:
Input: s = "a" Output: "a"
Example 4:
Input: s = "ac" Output: "a"
Constraints:
1 <= s.length <= 1000
s
consist of only digits and English letters (lower-case and/or upper-case),
思路:
经典老题最长回文子串,因为如果暴力搜索会达到,用DP降低到。建立二维bool数组f,数组中f[j][i]表示index j到index i的字串是不是回文。这里有个点是LeetCode现在C++代码中不允许bool f[n][n]这种初始化方式了,因此只能建立二维vector。原本如果可以用C的初始化方式,速度能快一半,几个月前还可以用这种方式骗解题速度,现在应该是被ban了。然后是数组初始化,显然对于f[i][i],因为它是单个字母,肯定是回文,所以都设成true。之后判断是否s[i]==s[j],如果相等那么就可以判断:如果i+1和j-1也是回文,那当前就肯定是回文,这里注意是往里缩的,比如"baab",这里b和b相等,如果中间aa是回文,那么baab肯定是回文。第一个b对应i,第二个b对应j。然后如果i-j<2,也可以判断这是个回文,比如“cbbd”,这里光靠s[i]==s[j]是不够的,因为我们无法判断i+1和j-1,这不在我们循环的范围内;所以如果i-j小于2,即要不i==j,这种情况我们已经考虑过,但是如果i=j+1,即两个b相邻,那么我们也可以判断是回文。以上就是转移方程,剩下的就是每次都记录最大长度和对应的字串即可。
代码:
class Solution {
public:
string longestPalindrome(string s) {
int n=s.size();
vector<vector<bool>> f(n,vector<bool>(n));
for(int i=0;i<n;i++)
f[i][i]=true;
int count = 1;
string ans=s.substr(0,1);
for(int i=0;i<n;i++)
{
for(int j=0;j<i;j++)
{
if(s[i]==s[j])
{
if(i-j<2||f[j+1][i-1])
f[j][i]=true;
}
if(f[j][i]&&i-j+1>count)
{
count=i-j+1;
ans=s.substr(j,i-j+1);
}
}
}
return ans;
}
};