5.最长回文子串--中等

题目说明

给你一个字符串 s,找到 s 中最长的回文子串。
如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。

示例1

输入:s = "babad"
输出:"bab"
解释:"aba" 同样是符合题意的答案。

示例2

输入:s = "cbbd"
输出:"bb"

思路:

中心扩散法

大致做法就是遍历字符串,对于当前的字符,依次找其两侧的字符是否对称。
比如对于一个字符串“acbddbee”,若当前字符为第一个d(位置下标为3),用cur、left和right分别记录当前遍历的字符、当前字符的左边和右边位置,则:

  • 向右边一直寻找(left--)与当前字符(cur)相同的字符;
  • 向左边一直寻找(right++)与当前字符(cur)相同的字符;
  • 最后左右一起同时扩散(left-- and right++),寻找左边和右边相等(left对应的字符 == right对应的字符)的字符。

为什么要分这三步进行?

我们可以分析一下回文串的情况,回文串可分为三种情况:

  1. 全部一模一样,如“cccccc”;
  2. 字符不尽相同但对称,又可细分为两种:“acdca”和“abba”;
  3. 以及二者的混合:如“abcccccba”;
    对于1和3的情况,我们都需要中心扩散法的前两步找到回文串中完全相同的部分,然后再开始找不同但对称的部分

代码

#include <string>
using namespace std;

string func(string s){
    int begin = 0;
    int end = 0;
    int right, left;
    for(int i=0; i<s.size(); i++) {
        left = i - 1;
        right = i + 1;
        while (left >= 0 && s[left] == s[i]) {
            left--;
        }
        while (right < s.size() && s[right] == s[i]) {
            right++;
        }
        while (left >= 0 && right < s.size() && s[left] == s[right]) {
            left--;
            right++;
        }
        if (end - begin < right - left) {
            begin = left + 1;
            end = right-1;
        }
    }
    return s.substr(begin, end - begin + 1);
}

posted on 2023-05-12 16:51  笑嘻嘻嘻了  阅读(42)  评论(0)    收藏  举报

导航