/*5. 最长回文子串
给你一个字符串 s,找到 s 中最长的回文子串。
如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。
输入:s = "babad"
输出:"bab"
解释:"aba" 同样是符合题意的答案。*/
/*5. 最长回文子串
给你一个字符串 s,找到 s 中最长的回文子串。
如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。
输入:s = "babad"
输出:"bab"
解释:"aba" 同样是符合题意的答案。*/
//动态规划:核心就是发现一个最优结构使得当前的结果可以用之前计算过的结果表示
//如果当前子串是回文结构,那么它内部对称子串也是回文结构
#include<stdio.h>
#include<math.h>
#include<string.h>
char* longestPalindrome(char* s) {
int len=strlen(s);
printf("%d\n",len);
int start=0; //为了输出
int len_string=0; //输出字串的长度
int dp[len][len];
memset(dp, 0, sizeof(dp));//用一个 二维数组来记录回文串 如果是回文串的话记作1
for(int i=0;i<len;i++){
dp[i][i]=1;
考虑单个字符是否是回文串
if(s[i+1]==s[i]){
dp[i][i+1]=1; //如果相邻两个字符相同,一定为回文串
}
}
//把二维数组补全,只考虑j>i的部分即可。
for(int i=0;i<len-2;i++){
for (int j=i+2;j<len;j++){
if(dp[i+1][j-1]==1){
if(s[i]==s[j]){
dp[i][j]=1;
}
}
}
}
for(int i=0;i<len;i++){
for(int j=0;j<len;j++){
if(dp[i][j]==1){
len_string=fmax(len_string,j-i+1);
}
}
}
for(int i=0;i<len;i++){
for(int j=0;j<len;j++){
if(dp[i][j]==1){
if(j-i+1==len_string){
start=i;
}
}
}
}
for(int i=0;i<len;i++){
for(int j=0;j<len;j++){
printf("%d",dp[i][j]);
}
printf("\n");
}
static char res[1000];
strncpy(res,s+start,len_string);
res[len_string]='\0';
return res;
}
int main(){
char s[1000]="aaaaa";
printf("%s",longestPalindrome(s));
return 0;
}
错误做法
上述代码在求解二维数组时候出了问题,将二维数组输出发现:
我认为应该是在输入数组时有顺序问题,例如在为dp[0][4]时,需要知道dp[1][3]的值,但此时dp[1][3]还未被赋1;导致dp[0][4]=0,显然 上述错误代码赋值顺序是从右下开始。
正确做法
先确定字符串的长度,由短到长进行赋值。
char* longestPalindrome(char* s) {
int s_len=strlen(s);
int dp[s_len][s_len];
int s_hui=0;
int start=0;
memset(dp,0,sizeof(dp)); //初始化为0,以二维数组来记录回文串
for(int i=0;i<s_len;i++){
dp[i][i]=1;
s_hui=1;
start=i;
}
for(int i=0;i<s_len-1;i++){
if(s[i]==s[i+1]){
dp[i][i+1]=1;
s_hui=2;
start=i;
}
}
//记录k为回文串长度
for(int k=3;k<=s_len;k++){
for(int i=0;i<=s_len-k+1;i++){
int j=i+k-1;
if(s[j]==s[i]&&dp[i+1][j-1]==1){
dp[i][j]=1;
s_hui=k;
start=i;
}
}
}
s[start+s_hui]='\0';
s=&s[start];
return s;
}