目录
- 题目
- 1- 思路
- 2- 实现
- ⭐5. 最长回文子串——题解思路
- 3- ACM 实现
题目
- 原题连接:5. 最长回文子串
1- 思路
- 模式识别:最长回文子串——> 动规五部曲
- 子串的概念 ——> 子串是连续的部分,区别与子序列
动规五部曲
1.定义dp数组
dp[i][j]
代表[i...j]
区间内的子串是否是回文子串
2.递推公式
if(s.charAt(i)==s.charAt(j)) {
// 单个字符 没意义
if(j-i<3){
dp[i][j] = true;
}else{
dp[i][j] = dp[i+1][j-1];
}
}
3.初始化
- 主对角线的单个字符全都是 true
- 其中 dp[i][j] 参考了 当前位置 左下方的 值,因此需要注意遍历顺序
2- 实现
⭐5. 最长回文子串——题解思路
class Solution {
public String longestPalindrome(String s) {
// 1. 定义 dp 数组
int len = s.length();
boolean[][] dp = new boolean[len][len];
int maxLen = 1;
int begin = 0;
// 2. 递推公式
// 2.1 不等 为 false
// 2.2 相等小于 3 true ,否则 dp[i][j] = dp[i+1][j-1];
// 3. 初始化
for(int i = 0 ; i < len;i++){
dp[i][i] = true;
}
// 4. 遍历
for(int j = 1;j<len;j++){
for(int i = 0 ; i < j;i++){
if(s.charAt(i)!=s.charAt(j)){
dp[i][j] = false;
}else{
if(j-i<3){
dp[i][j] = true;
}else{
dp[i][j] = dp[i+1][j-1];
}
}
if(dp[i][j] && j-i+1 > maxLen){
maxLen = j-i+1;
begin = i;
}
}
}
return s.substring(begin,begin+maxLen);
}
}
3- ACM 实现
public class longestPlainDrome {
public static String longestSub(String s){
// 1.定义 dp
int len = s.length();
boolean[][] dp = new boolean[len][len];
int maxLen = 1;
int begin = 0;
// 2.递推公式
// i j 不等则为 false,j-i<3 为true 否则为 dp[i][j] = dp[i+1][j-1];
// 3.初始化
for(int i = 0 ; i < len;i++){
dp[i][i] = true;
}
// 4. 遍历顺序
for(int j = 1 ; j < len;j++){
for (int i = 0 ; i < j;i++){
if(s.charAt(i)!=s.charAt(j)){
dp[i][j] = false;
}else{
if(j-i<3){
dp[i][j] = true;
}else{
dp[i][j] = dp[i+1][j-1];
}
}
// max 和 begin 的更新
if(dp[i][j] && j-i+1 >maxLen){
maxLen = j-i+1;
begin = i;
}
}
}
return s.substring(begin,begin+maxLen);
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("输入字符串s");
String s = sc.next();
System.out.println("结果是"+longestSub(s));
}
}