对给定的字符串,本题要求你输出最长对称子串的长度。例如,给定
Is PAT&TAP symmetric?
,最长对称子串为s PAT&TAP s
,于是你应该输出11。输入格式:
输入在一行中给出长度不超过1000的非空字符串。
输出格式:
在一行中输出最长对称子串的长度。
输入样例:
Is PAT&TAP symmetric?
输出样例:
11
题目描述
现有一个字符串s,求s的最长回文子串的长度。
输入描述
一个字符串s,仅由小写字母组成,长度不超过
100
。输出描述
输出一个整数,表示最长回文子串的长度。
样例1
输入
lozjujzve输出
5解释
最长公共子串为
zjujz
,长度为5
。
题解(通用):动态规划
具体过程细节
- 初始化单个字符的回文状态:遍历字符串,将所有单个字符的回文状态设为
true
。- 初始化长度为 2 的子串的回文状态:遍历字符串,检查相邻两个字符是否相同,如果相同则将对应的 dp[i][i+1] 设为
true
,并更新 maxLength 为 2。- 动态规划求解更长子串的回文状态:从长度为 3 的子串开始,逐步增加子串长度,直到整个字符串的长度。对于每个长度的子串,检查两端字符是否相同且去掉两端字符后的子串是否是回文子串,如果是,则更新 dp[i][j] 为
true
,并更新 maxLength。
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1010;//开大于1000的,否则出错
int main()
{
string s;
getline(cin, s);
int n = s.size();
int maxLength = 1;
vector<vector<bool>> dp(MAXN,vector<bool>(MAXN, false));
//bool dp[MAXN][MAXN];
// 初始化单个字符的回文状态
for(int i=0;i<n;i++){
dp[i][i] = true;
}
// 初始化长度为 2 的子串的回文状态
for(int i=0;i<n-1;i++){
if(s[i] == s[i+1]){
dp[i][i+1] = true;
maxLength = 2;
}
}
for(int i=3;i<=n;i++){ //外层循环表示长度,从长度3开始遍历
for(int j=0;j+i-1<n;j++){ 当长度为i时,从j开始的子串的末尾下标为j+i-1,要求不超过n 越界
int k = j+i-1; //子串的尾下标
if(s[j] == s[k] && dp[j+1][k-1]){
dp[j][k] = true;
maxLength = i;
}
}
}
cout<<maxLength;
return 0;
}
题解二:
使用双重循环遍历所有可能的子串。
对于每个子串,调用
huiwen
函数判断是否是回文。如果是回文,则更新
maxLength
。时间复杂度:O(n3),其中 n 是字符串的长度。
#include <bits/stdc++.h>
using namespace std;
bool huiwen(string s){
int len = s.size();
for(int i=0;i<len/2;i++){
if(s[i] != s[len-1-i]){
return false;
}
}
return true;
}
int main()
{
string s;
getline(cin, s);
int n = s.size();
int maxLength = 1;
for(int i=0;i<n;i++){
for(int j=i+1;j<n;j++){
string s1 = s.substr(i, j-i+1);
if(huiwen(s1)){
int len = s1.size();
maxLength = max(maxLength, len);
}
}
}
cout<<maxLength;
return 0;
}