题目描述
- 给你一个字符串 s,找到 s 中最长的回文子串。
最长回文子串是一个字符串中最长的回文子串。回文是指正着读和倒着读都一样的字符串。例如,字符串 “babad” 中的最长回文子串为 “bab” 或 “aba”。
实现最长回文子串的算法有多种,其中最常见的是动态规划算法和中心扩展算法。
动态规划算法的基本思想是将问题分解成更小的子问题,然后通过子问题的解来求解原问题的解。对于最长回文子串问题,可以定义一个二维数组 dp[i][j] 表示字符串从 i 到 j 的子串是否为回文串。如果 dp[i][j] 为 true,则表示字符串从 i 到 j 是回文串,否则不是回文串。状态转移方程为:
dp[i][j] = (s[i] == s[j] && dp[i + 1][j - 1])
其中 s[i] 表示字符串的第 i 个字符。如果 s[i] 等于 s[j] 且 dp[i+1][j-1] 也为 true,则 dp[i][j] 也为 true。需要注意的是,当 i=j 时,dp[i][j] 必然为 true。
中心扩展算法的基本思想是从每个字符和每两个字符之间开始向两边扩展,直到不是回文串为止,记录每个回文串的长度,最后返回最长的回文串。具体实现方式如下:
1. 从左到右遍历字符串,以每个字符为中心向两边扩展,记录回文串的长度。
2. 从左到右遍历字符串,以每两个字符之间为中心向两边扩展,记录回文串的长度。
3. 返回最长的回文串。
需要注意的是,回文串可能是奇数长度或偶数长度,所以需要分别考虑。
暴力解法
class Solution {
public:
string longestPalindrome(string s) {
string res = s.substr(0,1);
for(int i=0;i<s.size();i++){
for(int j=i+1;j<s.size();j++){
if(j-i+1>res.size() && isPalindrome(s,i,j)){
res = s.substr(i,j-i+1);
}
}
}
return res;
}
bool isPalindrome(string& str, int left ,int right){
while(left<= right){
if(str[left] != str[right]){
return false;
}
left++;
right--;
}
return true;
}
};