持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第15天,点击查看活动详情
1、前言
每天一个算法小练习,本篇使用Java实现。
2、题目描述
给你一个字符串 s,找到 s 中最长的回文子串。
- 1 <= s.length <= 1000
- s 仅由数字和英文字母组成
2.1、示例1
输入:s = "babad"
输出:"bab"
解释:"aba" 同样是符合题意的答案。
2.2、示例2
输入:s = "cbbd"
输出:"bb"
3、解题思路
这道题,在之前的面试中也遇到过好几次,出现频率还是挺高的。最简单的就是暴力法 - 双层for循环,遍历区间起始位置和终止位置,然后判断这个区间是不是回文。当然这种并不推荐,因为时间复杂度未。可以用另一种方法,动态规划解决。
- 双层for循环
public String longestPalindrome(String s) {
//翻转字符串
String reStr = new StringBuffer(s).reverse().toString();
int maxLen = 0;
int maxEnd = 0;
int len = s.length();
int[][] arr = new int[len][len];
for (int i = 0; i < len; i++) {
for (int j = 0; j < len; j++) {
if (s.charAt(i) == reStr.charAt(j)) {
if (i == 0 || j == 0) {
arr[i][j] = 1;
} else {
arr[i][j] = arr[i - 1][j - 1] + 1;
}
}
if (arr[i][j] > maxLen) {
int beforeRev = len - 1 - j;
//判断下标是否对应
if (beforeRev + arr[i][j] - 1 == i) {
maxLen = arr[i][j];
maxEnd = i;
}
}
}
}
return s.substring(maxEnd - maxLen + 1, maxEnd + 1);
}
执行结果:
-
时间复杂度:。
-
空间复杂度:。
动态规划
public String longestPalindrome(String s) {
int n = s.length(), max = 1;
//dp记录从i到j的字串是否为回文串
boolean[][] dp = new boolean[n][n];
char[] chars = s.toCharArray();
//记录最长回文串
String resStr = s.substring(0,1);
for(int i = 0; i < n; i++){
for(int j = 0; j <= i; j++){
boolean iEqJ = chars[i] == chars[j];
boolean dpIJ = (i - j <= 1||dp[j+1][i-1]);
if(iEqJ && dpIJ){
dp[j][i]=true;
if(i - j + 1 > max){
max = i - j + 1;
resStr = s.substring(j, i + 1);
}
}
}
}
return resStr;
}
执行结果:
-
时间复杂度:。
-
空间复杂度:。
好了、本期就先介绍到这里,有什么需要交流的,大家可以随时私信我。😊