题目
给你一个字符串 s
,找到 s
中最长的回文子串
(如果字符串的反序与原始字符串相同,则该字符串称为回文字符串.)
示例 1:
输入:s = "babad" 输出:"bab" 解释:"aba" 同样是符合题意的答案。
示例 2:
输入:s = "cbbd" 输出:"bb"
提示:
1 <= s.length <= 1000
s
仅由数字和英文字母组成
回文天然具有「状态转移」性质:一个回文去掉头尾字符以后,剩下的部分依然是回文。反之,如果一个字符串头尾两个字符都不相等,那么这个字符串一定不是回文。「动态规划」的方法根据这样的性质得到。
dp[i][j]
表示:子串 s[i..j]
是否为回文子串,这里子串 s[i..j]
定义为左闭右闭区间,即可以取到 s[i]
和 s[j]
dp[i][j]定义为bool类型,表示从s中i到j的字符串是否为真
代码
class Solution {
public:
string longestPalindrome(string s) {
// sz代表字符串长度,剩下变量分别用于记录最长回文子串起始点以及最大长度
int sz = s.size();
int start = 0;
int max = 1;
// 开一个行和列长度都为sz的bool类型的二维数组,记录子串是否满足回文
vector<vector<bool>> dp(sz, vector<bool> (sz));
// 从第字符串二个位置开始,从头往后找到这个位置,判断路径上的串是否回文
for(int j = 1; j < sz; ++j)
{
for (int i = 0; i < j; ++i)
{
// 若发现最左和最右满足回文条件
if (s[i] == s[j])
{
// 若其长度等于2或者3,则直接判定为回文串,令其为true
if (j-i == 1 || j-i == 2)
dp[i][j] = true;
else
{ // 若长度大于3,则看看除开左右两头的,中间子串是否为回文
if (dp[i+1][j-1] == false)
continue;
// 子串为回文,则当前串也为回文,令其为true
dp[i][j] = true;
}
// 若当前串为回文,而且长度大于最大长度,则更新起点与及长度
if (dp[i][j] == true && (j-i+1) > max)
{
max = j-i+1;
start = i;
}
}
}
}
return s.substr(start, max);
}
};
提交结果