题目(短小而精炼~):
给你一个字符串 s,找到 s 中最长的回文子串。
示例 1:
输入:s = “babad”
输出:“bab”
解释:“aba” 同样是符合题意的答案。
示例 2:
输入:s = “cbbd”
输出:“bb”
示例 3:
输入:s = “a”
输出:“a”
示例 4:
输入:s = “ac”
输出:“a”
有两个想法: 一个是参考647.回文子串选出回文子串的类似思路 来使用双指针来获取最长的回文子串; 二是使用动态规划进行求解
法一 :(双指针)
class Solution {
public:
string Palindrome(string s, int start, int end){ // 判断字符串 以中心点向外拓展
// 防止索引越界
while(end<s.length() && start>=0 && s[start] == s[end])
{
start--;
end++;
}
// 从 while 循环 退出来的时候 s[start+1] 到 s[end-1] 是正常的(符合回文串)
// 期间的距离为 end-1-start-1+1 = end-start-1
return s.substr(start+1, end-start-1);
// str.substr(起点, 距离)(截取部分字符串) 起点 start+1 结尾 end-1 距离 end-start+1
}
string longestPalindrome(string s) {
if(s.length() == 1) return s;
int len = s.length();
string res = "";
for(int i = 0;i<len;i++)
{
string s1 = Palindrome(s,i,i); // 当字符串长度
string s2 = Palindrome(s,i,i+1); // 当字符串长度为偶数的时候, 中心点可能为i 可能为 i+1
res = res.length()>s1.length()?res:s1; // 比较 s1 和 s2的长度
res = res.length()>s2.length()?res:s2;
// res = max(res,s1,s2);
}
return res;
}
};
时间复杂度: O(n^2), 空间复杂度: O(1)
法二 :
class Solution{
public:
string longestPalindrome(string s){
if(s.length() == 1) return s;
int len = s.length(),maxlen = 0,left = 0;
// maxlen为最长回文子字符串的长度, 而left则是标记回文字符串的起点
vector<vector<bool>>dp(len,(vector<bool>(len,false)));
for(int i = len-1;i >= 0; i--){
for(int j = i;j < len; j++){
if(s[i] == s[j]){ // 标识出回文串的边界位置
if(j-i <= 1){ // 相差一个位置的回文字符串
dp[i][j] = true;
}
// 初始完后 可以计算最长字符串的左边界 以及 长度了
else if(dp[i+1][j-1]){
dp[i][j] = true;
}
}
if(dp[i][j] && j-i+1 > maxlen){ // 时刻更新最长回文子字符串
maxlen = j-i+1;
left = i;
}
}
}
return s.substr(left, maxlen);
}
};
时间复杂度: O(n^2), 空间复杂度: O(n^2)
此题的分享就到此结束啦~ 😃
欢迎各位前来共同学习, 若有疑问或者要讨论的, 欢迎在下方评论区留言, 谢谢大家~