題目描述(難度中)
給定一個字符串 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);
}
};