1. 理解回文子串问题
回文子串是算法面试中的经典问题,也是字符串处理的基础题型之一。所谓回文串,指的是正读和反读都相同的字符串,比如"aba"、"abba"、"a"都是回文串。而最长回文子串问题,就是要求我们在给定的字符串中找出最长的那个回文子串。
这个问题看似简单,但想要高效解决却需要一些技巧。暴力解法虽然直观,但时间复杂度高达O(n³),显然不适合处理较长的字符串。而动态规划方法可以将时间复杂度优化到O(n²),是更优的选择。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 动态规划解法详解
2.1 动态规划思路解析
动态规划解决这个问题的核心思想是利用已经计算过的子问题的解来构建更大问题的解。我们定义一个二维数组dp,其中dp[i][j]表示字符串s从i到j的子串是否是回文串。
状态转移方程如下:
- 当j - i <= 2时(即子串长度为1、2或3),dp[i][j] = (s[i] == s[j])
- 当j - i > 2时,dp[i][j] = (s[i] == s[j]) && dp[i+1][j-1]
这个方程的意思是:一个较长的子串要成为回文串,首先它的首尾字符必须相同,其次去掉首尾后的子串也必须是回文串。
2.2 代码实现解析
让我们仔细分析提供的代码实现:
cpp复制class Solution {
public:
string longestPalindrome(string s) {
int n = s.length();
int st = 0; // 记录最长回文子串的起始位置
int maxlen = 1; // 记录最长回文子串的长度,初始为1(单个字符)
// 初始化动态规划表
vector<vector<bool>> f;
for(int i = 0; i < n; i++) {
vector<bool> row(n, false);
f.push_back(row);
}
// 单个字符都是回文串
for(int i = 0; i < n; i++) {
