这是我参与8月更文挑战的第26天,活动详情查看:8月更文挑战
题目
给你一个字符串 s,找到 s 中最长的回文子串。
示例
输入: s = "babad"
输出: "bab"
解释: "aba" 同样是符合题意的答案。
输入: s = "cbbd"
输出: "bb"
输入: s = "a"
输出: "a"
输入: s = "ac"
输出: "a"
提示
1 <= s.length <= 1000s仅由数字和英文字母(大写和/或小写)组成
解题思路
针对子串问题,一般都可以通过 n - 1 来推导出 n 的值,在本题中,我们也可以通过同样的思路来进行推导。
- 定义好数组
dp[n][n],初始化每位元素初始值为true - 由小区间往大区间拓展 , 便于后续推导
- 判断当前区间首尾两元素是否相同
- 更新结果,截取子字符串返回
代码实现
class Solution {
public String longestPalindrome(String s) {
char[] c = s.toCharArray();
int n = c.length;
int maxLen = 1;
int begin = 0;
boolean[][] dp = new boolean[n][n];
// 初始化每位元素
for(int i = 0; i < n; ++i){
dp[i][i] = true;
}
// 从长度为2开始,逐渐扩展
for(int i = 2; i <= n; ++i){
int k;
// 向后推导当前长度下,改区间是否为回文串
for(int j = 0; j < n; ++j){
k = i + j - 1;
if(k >= n){
break;
}
// 首尾两元素不相同则当前区间不为回文串
if(c[j] != c[k]){
dp[j][k] = false;
// 首尾两元素相同,且区间长度小于3则必定为回文串
}else if(k - j < 3){
dp[j][k] = true;
// 根据子区间得到当前区间的状态
}else{
dp[j][k] = dp[j + 1][k - 1];
}
// 更新结果
if(dp[j][k] && k - j + 1 > maxLen){
maxLen = k - j + 1;
begin = j;
}
}
}
// 返回结果
return s.substring(begin, begin + maxLen);
}
}
复杂度分析
- 时间复杂度:O(NN)
- 空间复杂度:O(NN)
最后
文章有写的不好的地方,请大佬们不吝赐教,错误是最能让人成长的,愿我与大佬间的距离逐渐缩短!
如果觉得文章对你有帮助,请 点赞、收藏、关注、评论 一键四连支持,你的支持就是我创作最大的动力!!!