每日一题&&学习笔记
给你一个字符串 s
,找到 s
中最长的回文子串。
示例 1:
输入:s = "babad" 输出:"bab" 解释:"aba" 同样是符合题意的答案。
示例 2:
输入:s = "cbbd" 输出:"bb" 提示:
1 <= s.length <= 1000
s
仅由数字和英文字母组成
class Solution {
public:
string longestPalindrome(string s) {
//获取字符串的长度
int n=s.size();
//判断若长度小于2,则直接返回字符串
if(n<2){
return s;
}
//定义变量存储回文串最大长度和起始位置
int maxlen=1;
int begin=0;
//定义dp存储i到j的子串
vector<vector<int>> dp(n,vector<int>(n));
//初始化所有长度为1的子串都是回文串
for(int i=0;i<n;i++){
dp[i][i]=true;
}
//枚举子串长度
for(int len=2;len<=n;len++){
//枚举左边界
for(int i=0;i<n;i++){
//定义右边界的下标
int j=len+i-1;
//若超出字符串长度,则退出循环
if(j>=n){
break;
}
//若左右边界字符不相等,则不为回文串
if(s[i]!=s[j]){
dp[i][j]=false;
}else{
//左边边界相等的情况下且字符串长度小于4,则为回文串
if(j-i<3){
dp[i][j]=true;
}else{
//若左右边界相等且长度大于4,则找该串除左右边界的子串是否为回文串
//其实这一行代码是整个动态规划算法的核心
//假设我们已知aa为回文串,则为它加上左右边界相等的字母b,也是回文
//实际上我们先确定了dp[i+1][j-1]是否为回文串
//然后在加上左右相等的边界,即dp[i][j]
dp[i][j]=dp[i+1][j-1];
}
}
//若当前子串为回文串且串长度大于当前最大串长度
if(dp[i][j]&&j-i+1>maxlen){
//则给串最大长度和串起始位置重新赋值
maxlen=j-i+1;
begin=i;
}
}
}
//返回找到的最长回文子串
return s.substr(begin,maxlen);
}
};
这道题转化为动态规划的思想,找常规字符串中的最长回文子串,就是先固定子串长度,然后左边界从0开始枚举,确定左边界和子串长度后,右边届也可以确定。这样就可以先找到较短的且靠前的回文子串,然后加大子串长度,左边界始终从0开始找。这样其实从长度为2的子串开始,我们已经判断了每一个可能的子串是否为回文串。所以这里动态规划的思想其实是从最小子串长度开始判断每一个子串是否为回文串,然后再加上相同的左右边界,则他是否回文就可以从之前的子串中得出,若他左右不相等,则直接判断为不是回文串。然后再判断一个左右边界和字符串长度即可。
原文地址:https://blog.csdn.net/m0_73096516/article/details/142830432
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!