题目描述(难度中)
给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
示例 1:
输入: “babad”
输出: “bab”
注意: “aba” 也是一个有效答案。
示例 2:
输入: “cbbd”
输出: “bb”
链接
https://leetcode-cn.com/problems/longest-palindromic-substring/
思路
1、暴力解法。
2、以每个字符为中心向两边拓展(我第一时间想到的方案,能过LeetCode测试用例),需要分奇数和偶数情况进行讨论。
3、动态规划
dp[i][j]
表示字符串从 j
到 i
是否是为回文串,即当 s[j] == s[i]
如果 dp[i-1][j+1]
也是回文串,那么字符串从 j
到 i
也是回文串,即 dp[i][j]
为真。
代码
中心拓展方案:
class Solution {
public:
string longestPalindrome(string s) {
string ans = s.substr(0, 1);
for(int i = 1; i < s.length(); i++){
// 在每一个位置,判断当前位置为中心的回文串和当前位置和前一个位置为中心的回文串
// 当前位置为中心
int left = i;
int right = i;
while(left >= 0 && right <= s.length()-1 && s[left] == s[right]){
left--;
right++;
}
if(right-left-1 > ans.length()){
ans = s.substr(left+1, right-left-1);
}
// 当前位置和前一个位置为中心
left = i - 1;
right = i;
while(left >= 0 && right <= s.length()-1 && s[left] == s[right]){
left--;
right++;
}
if(right-left-1 > ans.length()){
ans = s.substr(left+1, right-left-1);
}
}
return ans;
}
};
动态规划方案:(注意规划方向)
class Solution {
public:
string longestPalindrome(string s) {
bool dp[1001][1001] = {0};
int ansStart = 0;
int ansLen = 1;
for(int i = 0; i < s.length(); i++){
dp[i][i] = true;
if(i < s.length() - 1 && s[i] == s[i+1]){
dp[i][i+1] = true;
ansStart = i;
ansLen = 2;
}
}
for(int k = 3; k <= s.length(); k++){ // 表示子串长度
for(int i = 0; i+k-1 < s.length(); i++){ // 表示需要判定的字符串的起始点
if(s[i] == s[i+k-1] && dp[i+1][i+k-2]){
dp[i][i+k-1] = true;
ansStart = i;
ansLen = k;
}
}
}
return s.substr(ansStart, ansLen);
}
};