给你一个字符串 s,找到 s 中最长的回文子串。
如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。
来源:力扣(LeetCode)链接:https://leetcode.cn/problems/longest-palindromic-substring/
自己的思路:
编写一个判断回文数函数,设定i,j,k,一个len=1,一个返回字符串w, k遍历字符串,i=k遍历,j从字符串尾部开始向前遍历,直到j<i时停止,如果s[i]!=s[j],j自减,如果相等将i到j的字符合并为一个新字符串,再它判断是否为回文数,若是回文数,比较新字符串与len的大小,若新字符串大于len,将新字符的长度赋值给len,新字符串赋值给字符串w,遍历结束后返回w就找到最大回文数字串。
C语言(字符串太长会超时。。):
//判断回文数
intHui(char*str)
{
inti,n=0,fg=1; //设置标志位
char*p=str;
while(*p){ //将指针p置位到字符串末尾,并统计字符数
n++;
p++;
}
for(i=0;i<n/2;i++){ //循环比较字符
if(str[i]==str[n-1-i]); //相同,什么都不作
else{ //否则,直接跳出循环
fg=0;
break;
}
}
returnfg;
}
char*longestPalindrome(char*s){
staticcharw[1000];
inti,j,k;
intflag=1;
intlen=1;
if(strlen(s)==1){
w[0]=s[0];
w[1]='\0';
}
for(k=0;k<strlen(s)-1;k++){
i=k;
j=strlen(s)-1;
if(flag!=0){
w[0]=s[i];
w[i+1]='\0';
}
while(i!=j){
charb[1000];
intg=0;
if(s[i]!=s[j]){
j--;
}else{
flag=0;
j--;
for(intm=i;m<strlen(s);m++){
b[g++]=s[m];
}
b[j-i+2]='\0';
if(Hui(b)){
if(strlen(b)>len){
len=strlen(b);
strcpy(w,b);
}
}
}
}
}
returnw;
}
佬的思路:
遍历字符串
对于每个字母,向两侧扩散,判断是否回文子串
若为回文子串,保存最长的子串信息
子串长度为奇数或偶数,需分别判断
C语言:
作者:penn-10链接:https://leetcode.cn/problems/longest-palindromic-substring/solution/cyu-yan-zui-chang-hui-wen-zi-chuan-by-penn-10/
voidhelp(char*s, intN, intleft, intright, int*start, int*len) {
while (left>=0&&right<N&&s[left] ==s[right])
left--, right++;
if (right-left-1>*len) { // 如果找到更长的子串,保存其信息
*start=left+1;
*len=right-left-1;
}
}
char*longestPalindrome(char*s){
intN=strlen(s), start=0, len=0; // N 字符串长度, start 子串起始位置, len 子串长度
for (inti=0; i<N; i++) // 奇数长度的回文子串
help(s, N, i-1, i+1, &start, &len);
for (inti=0; i<N; i++) // 偶数长度的回文子串
help(s, N, i, i+1, &start, &len);
s[start+len] ='\0'; // 原地修改返回
returns+start;
}
// 时长:12ms 空间:6MB
Go语言:
枚举每个奇偶长度的回文串的中心起点,找最长的可能性
作者:himymBen链接:https://leetcode.cn/problems/longest-palindromic-substring/solution/pythongo-zhong-xin-kuo-zhan-by-himymben-xts8/
funclongestPalindrome(sstring) (resstring) {
varresstring;
fori, n :=0, len(s); i<n; i++ {
l, r :=i, i
forl>=0&&r<n&&s[l] ==s[r] {
l--
r++
}
ifr-l-1>len(res) {
res=s[l+1:r]
}
l, r=i, i+1
forl>=0&&r<n&&s[l] ==s[r] {
l--
r++
}
ifr-l-1>len(res) {
res=s[l+1:r]
}
}
returnres
}
// 时长:4ms 空间:2.3MB
总结:
这道题对于我来说和第3天一样暴力方法,由于进行了3次循环,遍历了每一个头尾一样的子串,字符串太长超时了,在看了佬的思路后,找回文数还可以就在一次遍历里发散,学到了学到了,明天继续加油!动态规划,保存历史记录是动态规划常用的技巧,最优子结构才是本质。
收获:
C语言字符串返回值的方法,动态规划初了解。
学习链接:
C语言字符串返回值方法-https://blog.csdn.net/luna_zhan/article/details/80433196