给你一个字符串s,找到s中最长的回文子串。
“如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。”
输入:s = "babad"
输出:"bab"
中心扩展算法
思路:回文字符串有两种类型,比如 aba 或者 abbc。
第一种是一个中心点往两边扩展;
第二种是两个中心点往两边扩展;
遍历中心点,使用双指针往两边扩展,如果两边的字母相同,就可以继续扩展;如果两边的字母不同,就停止扩展,取两种情况的最大子串
参考程序:
def longestPalindrome(s): start, end = 0, 0 for i in range(len(s)): l1, r1 = expandAroundCenter(s, i, i) # 中心为奇数 b a b l2, r2 = expandAroundCenter(s, i, i + 1) # 中心为偶数 b aa b if r1 - l1 > end - start: start, end = l1, r1 if r2 - l2 > end - start: start, end = l2, r2 return s[start:end + 1] def expandAroundCenter(s, l, r): while l >= 0 and r < len(s) and s[l] == s[r]: # 字母相同,继续扩展 l -= 1 r += 1 return l + 1, r - 1 # 返回下标 s = "babab" print(longestPalindrome(s))
如果有兴趣可以尝试动态规划的方法,仅提供思路。
动态规划
思路:使用动态规划算法解题步骤
定义状态:
我们可以定义 dp[i][j] 表示从索引 i 到 j 的子串是否为回文串。
初始化状态:
将所有长度为 1 的子串都初始化为回文,即 dp[i][i] = true。
检查所有长度为 2 的子串,如果两个字符相等,将 dp[i][i+1] 设为 true。
状态转移方程:
对于长度大于 2 的子串,dp[i][j] 是否为回文串取决于 dp[i+1][j-1] 和 s[i] == s[j]。
即dp[i][j] = dp[i+1][j-1] && s[i] == s[j]。
处理边界条件:
在上述初始化中已经处理了长度为 1 和 2 的情况。
自底向上构建解:
通过两层嵌套循环,自底向上地填充 dp 数组,从小规模子问题逐步构建到整个问题。
记录最优解:
在状态转移的过程中,不断更新记录最长回文子串的起始索引和长度。
返回结果:
最终,通过起始索引和长度,可以得到最长回文子串
本站内容未经许可,禁止任何网站及个人进行转载。