最长回文子串

题目:最长回文子串

给定一个字符串 s,求 s 中最长的回文子串。

解题思路

本方法采用 中心扩展法(Expand Around Center),以每个字符(或字符对)为中心向外扩展,找出最长回文子串。

1. 核心思想

任何回文字符串,都有一个 中心对称结构,可以分为:

1. 奇数长度的回文(如 "aba",中心是 'b')

2. 偶数长度的回文(如 "abba",中心是 bb)

我们可以:

• 以 每个字符 作为 奇数长度回文 的中心

• 以 相邻的两个字符 作为 偶数长度回文 的中心

然后 向外扩展,直到不再是回文。

2. 代码解析

class Solution {
public:
    string longestPalindrome(string s) {
        if (s.empty()) return "";  // 处理空字符串情况

        int start = 0, maxLen = 0;  // 记录最长回文子串的起始索引和长度

        for (int i = 0; i < s.size(); i++) {
            // 以 s[i] 为中心扩展(奇数长度)
            int len1 = expandFromCenter(s, i, i);
            // 以 s[i] 和 s[i+1] 为中心扩展(偶数长度)
            int len2 = expandFromCenter(s, i, i + 1);
            
            int len = max(len1, len2);  // 取最大回文长度

            if (len > maxLen) {  // 如果找到更长的回文,更新起点和长度
                maxLen = len;
                start = i - (len - 1) / 2;  // 计算回文起点
            }
        }
        return s.substr(start, maxLen);  // 返回最长回文子串
    }

    // 辅助函数:从中心点 (left, right) 开始向外扩展,返回回文长度
    int expandFromCenter(const string& s, int left, int right) {
        while (left >= 0 && right < s.size() && s[left] == s[right]) {
            left--;   // 左指针左移
            right++;  // 右指针右移
        }
        return right - left - 1;  // 计算回文长度
    }
};

3. 具体运行步骤

示例 1

输入:

s = "babad"

步骤:

i

expandFromCenter(s, i, i)

expandFromCenter(s, i, i+1)

取最大值

更新 start

maxLen

0

"b" → 1

"ba" → 0

1

0

1

1

"bab" → 3

"ba" → 0

3

0

3

2

"aba" → 3

"ad" → 0

3

1

3

3

"d" → 1

"da" → 0

1

-

-

4

"a" → 1

"a" → 0

1

-

-

输出: "aba" 或 "bab"

示例 2

输入:

s = "cbbd"

步骤:

i

expandFromCenter(s, i, i)

expandFromCenter(s, i, i+1)

取最大值

更新 start

maxLen

0

"c" → 1

"cb" → 0

1

0

1

1

"b" → 1

"bb" → 2

2

1

2

2

"b" → 1

"bd" → 0

1

-

-

3

"d" → 1

"d" → 0

1

-

-

输出: "bb"

4. 复杂度分析

时间复杂度: O(n²)

• 对于每个 i,调用 expandFromCenter 可能遍历整个字符串,因此最坏情况下 O(n²)。

空间复杂度: O(1)

• 只使用了常数级额外变量,不需要 dp 数组。

5. 总结

优点:

比 DP 方法更快,且省去 O(n²) 额外空间

容易实现,逻辑清晰

适用于一般字符串情况

缺点:

最坏情况下仍是 O(n²)

无法处理特殊优化情况,如 Manacher 算法可优化至 O(n)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值