最长回文子串

问题

给你一个字符串 s,找到 s 中最长的回文子串(是字符串中连续的非空字符序列)。

方案一:暴力枚举法

思路:从最长可能子串开始,逐层缩短长度,检查是否回文,第一个找到最长回文子串。
时间复杂度:O(n³)

#include <string>
#include <algorithm>
using namespace std;
class Solution {
public:
    string longestPalindrome(string s) {
        // 不能用int length = strlen(s); strlen(s)只能用于 char* ,string用.size() 或 .length()
        int length=s.size();
        for(int len=length;len>0;len--){
            for(int start=0;start+len<=length;start++){
                // c++没有s[start,start+len]的切片语法
                string sub=s.substr(start,len);

                // reverse的返回值是void,函数将字符串原地翻转,而不是返回翻转的值
                string rev=sub;
                reverse(rev.begin(),rev.end());
                
                // strcmp用于char*的比较,string使用==做字符串比较
                if (sub==rev){
                    return sub;
                }
            }
        }
        return "";        
    }
};

方案二:中心扩展法
思路:依次遍历字符串的每个字符,假定该字符为回文子串的中心(奇数情况),依次判断其左右字符是否相同并填充字符子串;考虑回文子串中心为两个相同字符的情况(偶数情况)。同时记录最长子串的开始位置和长度。
时间复杂度O(n²)

class Solution {
public:
    string longestPalindrome(string s) {
        if (s.empty()) return "";
        
        int start = 0, maxLen = 1;
        
        for (int i = 0; i < s.size(); i++) {
            // 奇数长度回文:中心是 s[i]
            expandAroundCenter(s, i, i, start, maxLen);
            // 偶数长度回文:中心是 s[i] 和 s[i+1]
            expandAroundCenter(s, i, i + 1, start, maxLen);
        }
        
        return s.substr(start, maxLen);
    }
    
private:
    void expandAroundCenter(const string& s, int left, int right, int& start, int& maxLen) {
        // 从中心向外扩展
        while (left >= 0 && right < s.size() && s[left] == s[right]) {
            int curLen = right - left + 1;
            if (curLen > maxLen) {
                maxLen = curLen;
                start = left;
            }
            left--;
            right++;
        }
    }
};
posted @ 2026-07-24 15:49  MyEngine  阅读(5)  评论(0)    收藏  举报