题目描述
给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
示例 1:
输入: “babad”
输出: “bab”
注意: “aba” 也是一个有效答案。
示例 2:
输入: “cbbd”
输出: “bb”
题目理解
区间DP的问题在腾讯笔试题中出现过,同样的套路:
1.首先确定初始条件,d[i][j] 表示 表示第i个到第j个字符是否是回文串
2.对区间分段,再对区间两端做处理
3.区间两端如果匹配,写出转移方程
4.区间两端不匹配,对区间做处理
在本题中回文字符串初始条件:回文字符串中字符串长度为0或1时都返回原字符串,长度为1时它就是一个回文串。同时对于两个元素的的也做初始判断,因为在字符串两端匹配的时候往内缩的时候d[i+1][j-1]就会报错,所以需要做初始化。
具体的理解可以见代码
package LC05_Longest_text;
import java.util.*;
public class Longest_text_string {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc=new Scanner(System.in);
String str=sc.nextLine();
int size=str.length();
//start,end记录回文字符串的下标
int start=0;
int end=0;
//d[i][j]表示第i个到第j个字符是否是回文串
boolean[][] d=new boolean[size][size];
//赋初值,自身这个字符是回文串
//对于len=1的也做单独处理,len=1时,d[i+1][j-1]会出错
//如cbbd,cb,d[1][0] bb,d[2][1],这时候进不去判断条件,实际bb是一个回文
for(int i=0;i<size-1;i++) {
d[i][i]=true;
if(str.charAt(i)==str.charAt(i+1)) {
d[i][i+1]=true;
start=i;
end=i+1;
}
}
d[size-1][size-1]=true;
//同样len表示区间步长,
for(int len=2;len<size;len++) {
for(int i=0;i<size-len;i++) {
//j表示区间末端
int j=i+len;
//针对区间作处理,赋初值
d[i][j]=false;
String test1=str.substring(i, j+1);//substring(i,j+1)实际截取的是i到j的子串
//区间两端有两种情况:
//1.匹配也就是字符相等,就将区间往内缩,转化成数学表达式就是d[i][j]=d[i+1][j-1]
//如果d[i+1][j-1]也是回文串我们就记录起始位置,因为步长是递增的,则相应start和end记录下的就是最长的
if(str.charAt(i)==str.charAt(j)&&d[i+1][j-1]) {
start=i;
end=j;
String test=str.substring(i, j+1);
System.out.println("LC text "+test);
d[i][j]=true;
}
//2.不匹配那就不是回文串,区间挪动,也就是i++
}
}
System.out.println(str.substring(start,end+1));
}
}