题目描述
给定一个仅包含小写字母的字符串,求它的最长回文子串的长度。
所谓回文串,指左右对称的字符串。
所谓子串,指一个字符串删掉其部分前缀和后缀(也可以不删)的字符串
(注意:记得加上while处理多个测试用例)
解题思路:
动态规划,dp数组的含义是:dp[i][j]代表从下标为j的位置到下标为i的位置的子串是否为回文数组。
递推公式:dp[i][j] = (str[i]==str[j]&&(i-j==1||dp[i-1][j+1]));
含义:如果(1)两端的字符相同且两个字符挨着。(2)或者两端字符相同且缩短的两端的字符串是一个回文数组。
满足以上两个条件之一的,则当前字符串也是一个回文数组。
错误点:
1.我原来内层循环使用j=i,j–,这是先计算Dp数组的较后位置的元素,此时前面位置的元素仍然未计算,所以肯定结果不正确。使用dp必须先计算前面位置数组的元素。
2.需要先将dp[i][i]初始化
3.需要记住二维数组的初始化方式vector<vector> dp(size,vector(size,false));
#include<iostream>
#include<vector>
using namespace std;
int main(){
string str;
cin>>str;
int size = str.size();
vector<vector<bool>> dp(size,vector<bool>(size,false));
int i,j,res=1;
for(int i=0;i<size;i++){
dp[i][i]=1;
}
for(i=0;i<size;i++){
for(j = 0;j < i;j++){
dp[i][j] = (str[i]==str[j]&&(i-j==1||dp[i-1][j+1]));
//dp[j][i] = (str[i]==str[j] && (i - j < 2 || dp[j + 1][i - 1]));
if(dp[i][j]){
res = max(i-j+1,res);
}
}
}
cout<<res<<endl;
}