题目描述
题干:
给你一个字符串 s,找到 s 中最长的回文子串。
示例1:
输入:s = "babad"
输出:"bab"
解释:"aba" 同样是符合题意的答案。
示例2:
输入:s = "cbbd"
输出:"bb"
示例3:
输入:s = "a"
输出:"a"
示例4:
输入:s = "ac"
输出:"a"
题解思路
答案不唯一的最长回文数,第一眼看到我觉得暴力解法和双指针方法都可以做,但是通不通过就不好说了,感觉会超过时间限制
我们直接来学习一下官方给出的动态规划思路吧,真的是惊得我目瞪口呆,借用二维数组来实现动态规划
核心思想是如果一个字符串两端的字符是相等的,那么就继续往中间判断,这样就可以把小问题的结果当成大问题的解
我们定义好要判断的字符串长度,然后从长度为1开始依次用二维数组来保存短的字符串是否为回文数
这样根据字符串长度越来越长,长度越长久就拿来代替ans返回,直到遍历完最长的字符串
这里有几个特殊情况,两端的时候不会是回文数,只有一个字符的时候也不会是,这样很多子串就可以直接赋值
正确代码
class Solution {
public String longestPalindrome(String s) {
int len = s.length();
boolean[][] dp = new boolean[len][len];
String ans = "";
for (int l = 0; l < len; ++l) {
for (int i = 0; i + l < len; ++i) {
int j = i + l;
if (l == 0) {
dp[i][j] = true;
} else if (l == 1) {
dp[i][j] = (s.charAt(i) == s.charAt(j));
} else {
dp[i][j] = (s.charAt(i) == s.charAt(j) && dp[i + 1][j - 1]);
}
if (dp[i][j] && l + 1 > ans.length()){
ans = s.substring(i,i+l+1);
}
}
}
return ans;
}
}
总结
说实话再让我遇到这道题我估计还得懵,但是动态规划的核心思想就是找到转换公式
让大问题的解运用子问题的解,用空间来换取时间,其实用动态规划方法的效率也不是很高
暴力解法的复杂度为O(n^3),动态规划的复杂度为O(n^2),官方还有一种 Manacher 算法复杂度达到了线性
不过囫囵吞枣终究是不好的,以后等自己技术再增长之后再来挑战吧,当然多学一种思想肯定是不赖的
如果文章存在什么问题或者有更好的题解,欢迎评论区斧正和评论,各自努力,你我最高处见