大佬救命,这段代码我看了2小时都没看懂

weixin_45906870 2020-07-24 09:52:14
题目:
给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。

示例1:
输入: "babad"
输出: "bab"
注意: "aba" 也是一个有效答案。

示例2:
输入: "cbbd"
输出: "bb"

代码如下:
char * longestPalindrome(char * s){
int N = strlen(s), start = 0, len = 0;
for (int i = 0; i < N; i++) {
int left = i - 1, right = i + 1;
while (left >= 0 && right < N && s[left] == s[right]){
left--; right++;
}
if (right - left - 1 > len) {
start = left + 1;
len = right - left - 1;
}
}
for (int i = 0; i < N; i++) {
int left = i, right = i + 1;
while (left >=0 && right < N && s[left] == s[right]) {
left--, right++;
}
if (right - left - 1 > len) {
start = left + 1;
len = right - left - 1;
}
}
s[start + len] = '\0';
return s + start;
}

这是LeetCode上的题目,看了很多题解也没看懂。求大佬帮我逐行逐句理清这个代码的思路。
...全文
120 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
weixin_45906870 2020-07-25
  • 打赏
  • 举报
回复
非常感谢
qybao 2020-07-25
  • 打赏
  • 举报
回复
找奇数回文从第二个元素到倒数第二个元素查找没问题,出现编译错误肯定是你的代码有问题。 一般来说奇数回文和偶数回文长度不可能一样长(奇数不可能等于偶数)。如果真出现回文一样长,那按现在的代码是奇数优先,因为if是判断是大于len才会交换,也就是等于len不交换,所以即使偶数回文长度和奇数回文一样也是奇数回文优先 一个字符算不算回文,这就看回文怎么定义了。顺着输出是该字符自己,逆着输出也是该字符自己,所以顺着和逆着一样,从这个角度看一个字符也算回文
wangdong20 2020-07-25
  • 打赏
  • 举报
回复
楼上说的很详细了,我补充下最后两句的意思
s[start + len] = '\0';
return s + start;
start是回文字符串在原字符串s的起始位置,len是回文字符串的长度,s[start + len] = '\0'; 把s字符串截断在start + len的位置上了,
return s + start;返回了原始字符串s中回文字符串的起始位置地址
weixin_45906870 2020-07-25
  • 打赏
  • 举报
回复
我还发现一个问题,当数组中没有回文字符串时,函数最后会返回数组中的第一个字符,难道一个字符也算回文字符串?
weixin_45906870 2020-07-25
  • 打赏
  • 举报
回复
引用 2 楼 wangdong20 的回复:
楼上说的很详细了,我补充下最后两句的意思
s[start + len] = '\0';
return s + start;
start是回文字符串在原字符串s的起始位置,len是回文字符串的长度,s[start + len] = '\0'; 把s字符串截断在start + len的位置上了,
return s + start;返回了原始字符串s中回文字符串的起始位置地址
如果目标数组中既然奇数回文又有偶数回文,再连续经过两个for循环最后return的回文是奇数还是偶数呢?上面的代码好像没有判断啊?
weixin_45906870 2020-07-25
  • 打赏
  • 举报
回复
引用 1 楼 qybao 的回复:
i从0位置开始不断右移,然后以i位置为中心,分别循环比较left和right的字符是否相等,如果不等,则while循环结束,然后判断left和right相等的字符的长度,如果长度大于最大值len,则说明以i为中心的回文更长,所以重新更新len以及回文的开始位置 举个例子 xabababa 当i移到第一个b位置,left和right字符都是a,是回文(aba),长度为3个字符,大于len0,所以更新len为3,start为1 当i移到第二个a位置,left和right的两个字符是ba,长度一共为5个字符(ababa),大于之前的len3,所以更新len为5,start为1 当i移动到第二个b位置,left和right的三个字符是aba,长度一共是7个字符(abababa),大于之前的len5,所以更新len为7,start为1 当i移动到第三个a位置,left和right的两个字符为ba,长度一共是五个字符(ababa),不大于之前的len7,所以不用更新len和start 后面依次类推 至于为什么用两次for i 循环 因为第一次for是为了找 abcba这种回文,也就是中心位和左右两边的字符不同,所以第一次for循环的left是从i-1开始算的 第二个for是为了找 abba这种回文,也就是没有中心位,就是直接左右对称的回文,所以第二次for的left是从i开始算的
第一个for循环的条件为什么不能改成for(int i=1;i小于N-1;i++)?既然是找奇数长度的回文,那么从第二个元素开始右移到倒数第二个元素不可以吗?可是我改成这样却会编译错误,错在哪?
qybao 2020-07-24
  • 打赏
  • 举报
回复
i从0位置开始不断右移,然后以i位置为中心,分别循环比较left和right的字符是否相等,如果不等,则while循环结束,然后判断left和right相等的字符的长度,如果长度大于最大值len,则说明以i为中心的回文更长,所以重新更新len以及回文的开始位置 举个例子 xabababa 当i移到第一个b位置,left和right字符都是a,是回文(aba),长度为3个字符,大于len0,所以更新len为3,start为1 当i移到第二个a位置,left和right的两个字符是ba,长度一共为5个字符(ababa),大于之前的len3,所以更新len为5,start为1 当i移动到第二个b位置,left和right的三个字符是aba,长度一共是7个字符(abababa),大于之前的len5,所以更新len为7,start为1 当i移动到第三个a位置,left和right的两个字符为ba,长度一共是五个字符(ababa),不大于之前的len7,所以不用更新len和start 后面依次类推 至于为什么用两次for i 循环 因为第一次for是为了找 abcba这种回文,也就是中心位和左右两边的字符不同,所以第一次for循环的left是从i-1开始算的 第二个for是为了找 abba这种回文,也就是没有中心位,就是直接左右对称的回文,所以第二次for的left是从i开始算的

69,373

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧