leetcode第5题,最长回文子串

一开始用的穷举法,时间直接超了,后来稍作修改才被accept,但是只是打败了70%的人。
后来找到了大神写的代码,现在直接粘上如下:
        if (s.size() < 2)
            return s;
        int len = s.size(), max_left = 0, max_len = 1, left, right;
        for (int start = 0; start < len && len - start > max_len/2;) 
        {
            left = right = start;
            while (right < len - 1 && s[right + 1] == s[right])
                ++right;
            start = right + 1;
            while (right < len - 1 && left > 0 && s[right + 1] == s[left - 1]) {
                ++right;
                --left;
            }
            if (max_len < right - left + 1) {
                max_left = left;
                max_len = right - left + 1;
            }
        }
        return s.substr(max_left, max_len);

start每次从上次的没有重复的right+1开始。
while (right < len - 1 && s[right + 1] == s[right])
++right;
这个循环语句是考虑有连续字符的情况,比如“cbbd”,如果没有这个循环 那么最后找到的答案是”c”,而不是“bb”。right一直加到没有相等字符为止(不管是奇数个bbb还是偶数个bb)都是回文。
再次考虑这个while循环的意义,如果连续字符的个数是奇数,比如说“cbbbd”,没有这个循环的话倒也检测得出来(从start等于2开始检测,可以检出中间的bbb),可是如果连续字符的个数是偶数,比如说“cbbd”,那么没有这个循环就检测不出来了。如果是”cbbbbd”,那么只能检测出三个。
综上,这个循环是很重要的。然后start每次都要在right的基础上加1。
后半部分的代码则很好理解了。
需要注意的是,for循环里的条件,不能将len-start>maxlen/2换成len-start>maxlen.否则的话,“kanana”返回的结果是”ana”,因为在start=3的时候len-start=3,而maxlen也等于3。
其实可以删去len-start>maxlen/2这句话,还是可以accepted。只不过最后会浪费一些时间。
这里的len-start>maxlen/2,maxlen/2选取的也很有讲究。从start开始,剩下的字符串长度就是len-start,那么可能的回文串就是两种情况,要么是len-start(连续的字符),要么是2(len-start)-1,所以要保证len-start>maxlen,或者2(len-start)-1>maxlen。而这里实际取了比这两个条件还要宽松的条件。也就是len-start>maxlen/2。就是为了宁愿浪费时间也不要漏掉。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值