「力扣」第 5 题:最长回文子串(暴力解法、中心扩散、动态规划)
解释题意
大家好,这里是「力扣」视频题解第 5 题:最长回文子串。
这道题给我们一个字符串 s,让我们找出这个字符串 s 的最长回文子串,并且告诉我们,s 的最大长度为 1000。
看到这个提示,我们简单计算一下,100010001000 的平方是 101010 的 666 次方,经验告诉我们,可以设计一个大欧 N 方的算法。(这里需要查相关资料说清楚。)
我们看一下示例 1:
给出的字符串是:babad,输出 bab,它是原始字符串的子串,并且 aba 也是一个有效的答案。
示例 2:
输入 cbbd,输出 bb。
由示例,我们可以归纳出回文子串的特点:
1、子串(substring):在原始字符串中必须是连续的字符,这一点是区别于子序列的,子序列()只需要保证字符的相对顺序不变,但不要求连续;
2、回文性质(palindromic):简单说就是从左向右读和从右向左读都是一样的。我们中国人是把回文玩得很 6 的,在古时候,我们就有回文对联和回文诗,有兴趣的朋友可以在网上搜索一下,「力扣」上也有很多关于回文串、回文子序列的问题,大家也不妨做一下。
回文性质从形象上说,就是在回文串的中心位置画一条直线,回文串关于这条直线中心对称。
关于回文,我们知道:
1、单个字符串一定是回文;
回文串可以根据其长度的奇偶性分类:
2、奇数长度的回文串:它的中心正好落在回文串的中间位置;
3、偶数长度的回文串:它的中心是两个相等的字符,也可以认为它的中心是这两个字符中间的空隙。
4、判定是否是回文字符串,可以从两边向中间同步遍历,即使用双指针成对地比较位于字符串前面和后面的字符,只要有一对字符不匹配,这个字符串就不是回文,直到双指针相遇,当且仅当全部匹配的时候,字符串才是回文。
另外一种方法是从回文串的中心开始向两边扩散去匹配,这个方法也很简单,要注意的一点是数组下标不能越界。
方法 1:暴力解法
最直接能够想到的方法是:
- 枚举
s的所有子串; - 然后逐个判断每个子串的回文性质;
- 同时记录最长子串;
- 细节:记录最长子串需要截取,截取有一定性能消耗。替代方式:记录最长回文子串的起始位置
start和最长回文子串的长度maxLen,到遍历完成以后,再做截取。
这一版代码交给读者完成。
Java 代码:
public class Solution {
// 暴力解法
public String longestPalindrome(String s) {
int len = s.length();
if (len < 2) {
return s;
}
int maxLen = 1;
String res = s.substring(0, 1);
// 枚举所有长度大于等于 2 的子串
for (int i = 0; i < len - 1; i++) {
for (int j = i + 1; j < len; j++) {
if (j - i + 1 > maxLen && valid(s, i, j)) {
maxLen = j - i + 1;
res = s.substring(i, j + 1);
}
}
}
return res;
}
private boolean valid(String s, int left, int right) {
// 验证子串 s[left, right] 是否为回文串
while (left < right) {
if (s.charAt(left) != s

本文探讨力扣第5题最长回文子串的三种解法:暴力解法、中心扩散法及动态规划法,分析每种方法的实现细节与复杂度。
最低0.47元/天 解锁文章
338

被折叠的 条评论
为什么被折叠?



