最长回文子串
题目描述:给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
示例 1:
输入: “babad”
输出: “bab”
注意: “aba” 也是一个有效答案。
示例 2:
输入: “cbbd”
输出: “bb”
思路分析:
解法一:暴力解法
暴力解法是最好想的一个方法,先写一个判断一个字符串是否为回文字符串的方法,然后从原字符串中分割子串挨个进行判断,要注意的是暴力选取的时候要从最长的子串开始选取。暴力解法虽然耗时长,但是面试的时候容易想,先把题目做出来是最重要的。
代码如下:
class Solution {
public String longestPalindrome(String s) {
if(s.length()==0) return "";
for(int i=s.length();i>0;i--){
for(int j=0;j<=s.length()-i;j++){
String str=s.substring(j,j+i);
if(isHuiWen(str)) return str;
}
}
return null;
}
public boolean isHuiWen(String s){
if(s.length()==1) return true;
for(int i=0;i<s.length()/2;i++){
if(s.charAt(i)!=s.charAt(s.length()-i-1)) return false;
}
return true;
}
}
解法二:动态规划
动态规划经常用来解决计算大量重叠子问题,动态规划的思想就是将之前的计算结果保存下来,避免重复计算,本质上是从空间换时间,对本题来说,可以创建一个二维boolean类型的矩阵dp,dp[i][j]表示字符串i与j索引间的子串是否为回文串。判断一个子串是否为回文串,首先该子串去除首尾字符应当为回文串,并且首尾字符相等。即 str[i]==str[j] && dp[i+1][j-1]
代码如下:
class Solution {
public String longestPalindrome(String s) {
if(s.length()==0) return "";
boolean[][] dp=new boolean[s.length()][s.length()];
int max=-1;
String res="";
for(int j=0;j<s.length();j++){
for(int i=0;i<=j;i++){
// if(i==j){
// dp[i][j]=true;
// }
if(s.charAt(i)==s.charAt(j) && j-i<=2){
dp[i][j]=true;
}
else if(s.charAt(i)==s.charAt(j) && dp[i+1][j-1]){
dp[i][j]=true;
}
if(dp[i][j] && j-i+1>=max){
max=j-i+1;
res=s.substring(i,j+1);
}
}
}
return res;
}
}
用时还是有点久,可能代码写得稍微有点问题
解法三:经典的马拉车(Manacher)算法