5. 最长回文子串
题目链接
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-palindromic-substring/
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
题目描述
给你一个字符串 s,找到 s 中最长的回文子串。
示例 1:
输入:s = “babad”
输出:“bab”
解释:“aba” 同样是符合题意的答案。
示例 2:
输入:s = “cbbd”
输出:“bb”
示例 3:
输入:s = “a”
输出:“a”
示例 4:
输入:s = “ac”
输出:“a”
提示:
1 <= s.length <= 1000
s 仅由数字和英文字母(大写和/或小写)组成
题目分析
暴力法-java
时间复杂度 o(n3)
空间复杂度o(1)
class Solution {
public String longestPalindrome(String s) {
if(s==null || s.length()<2){
return s;
}
int maxLen = 1;
int begin = 0;
char[] charArray = s.toCharArray();
for(int i=0;i<s.length()-1;i++){
for(int j = i+1;j<s.length();j++){
if(validPalindromic(charArray,i,j) && j-i+1>maxLen ){
begin = i;
maxLen = j-i+1;
}
}
}
return s.substring(begin,begin+maxLen);
}
//验证子串是否为回文
private boolean validPalindromic(char[] charArray, int left, int right){
while (left<right){
if(charArray[left] != charArray[right]){
return false;
}
left++;
right--;
}
return true;
}
}
中心扩散法-java
时间复杂度 o(n2)
空间复杂度 o(1)
//中心扩散法
class Solution {
public String longestPalindrome(String s) {
if(s==null || s.length()<2){
return s;
}
char []charArray = s.toCharArray();
int maxLen = 1;
int begin = 0 ;
for(int i=0;i<s.length()-1;i++){
int oldLen = expandAroundGenter(charArray,i,i);
int evenLen = expandAroundGenter(charArray,i,i+1);
int curMax;
if(oldLen>evenLen){
curMax = oldLen;
}else{
curMax = evenLen;
}
if(curMax>maxLen){
maxLen = curMax;
begin = i-(maxLen-1)/2;
}
}
return s.substring(begin,begin+maxLen);
}
//通过回文中心找回文串的长度
private int expandAroundGenter(char[] charArray,int left,int right){
while(left>=0 && right<charArray.length){
if(charArray[left] == charArray[right]){
left--;
right++;
}else{
break;
}
}
//注意这一步 right-left+1-2 并且不要减反
return right-left-1;
}
}
动态规划法
dp[i][j]是回文为true,不是回文为false。
动态转移方程 dp[i][j] = charArray[i]==charArray[j] and dp[i+1]dp[j-1]
边界条件 (j-1)-(i+1)+1<4
二维表格中 当前值需要参考左下方的值,所以要一列一列的填表。
class Solution {
public String longestPalindrome(String s) {
int n = s.length();
if(s==null || s.length()<2){
return s;
}
boolean dp[][] = new boolean[n][n];
char [] charArray = s.toCharArray();
int begin = 0;
int maxLen = 1;
for(int j=1;j<n;j++){
for(int i =0;i<j;i++){
if(charArray[i]==charArray[j]){
if(j-i+1 >=4){
dp[i][j] = dp[i+1][j-1];
}else{
dp[i][j] = true;
}
if(j-i+1>maxLen && dp[i][j]==true){//注意此步骤
maxLen = j-i+1;
begin = i;
}
}else{
dp[i][j] = false;
}
}
}
return s.substring(begin,begin+maxLen);
}
}