leetcode刷题记录——最长回文子串

给你一个字符串 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;

}

佬的思路:
  1. 遍历字符串

  1. 对于每个字母,向两侧扩散,判断是否回文子串

  1. 若为回文子串,保存最长的子串信息

  1. 子串长度为奇数或偶数,需分别判断

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

动态规划学习-https://zhuanlan.zhihu.com/p/91582909

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值