问题描述
给定一个字符串,如PATFTA
, 求其中的能构成回文的连续子串的最大长度;
解题思路
1.暴力解法
1.可以打两重循环,每次循环得到子串s[i]~s[j],再遍历s[i]~s[j],判断是否为回文串,取最大值;
2.这种做法的时间复杂度为O(n^3)
2.动态规划
1.令dp[i][j]表示子串s[i]~s[j]是否为回文串,是则为1,不是则为0;
2.易得只有当dp[i+1][j-1]为回文串的时候,dp[i][j]才有可能是回文串;
3.但是,如果以两个数组下标进行遍历的话,更新dp[i][j]时,dp[i+1][j-1]还没有计算,所以会出现错误;
4.因此,我们可以用数组下标+子串长度进行遍历;
5.除此之外,还需要初始化一下dp,让长度为1,2的回文串都判断出来,这样才能保证dp[i][j]更新时不用考虑dp[i+1][j-1]是否被计算;
代码展示
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e3+7;
/*
*/
bool dp[maxn][maxn];
int main(){
string s;
cin>>s;
int l=s.size();int ans=1;//回文子串最大长度
for(int i=0;i<l;i++){
dp[i][i]=1;
if(i<l-1&&s[i]==s[i+1]){
dp[i][i+1]=1;
ans=2;
}
}
//初始化
for(int len=3;len<l;len++){
for(int j=0;j+len-1<l;j++){
int k=j+len-1;
if(s[j]==s[k]&&dp[j+1][k-1]){
dp[j][k]=1;
ans=len;
}
}
}
cout<<ans<<endl;
return 0;
}