LeetCode之最长回文子串
一、题目描述
二、解题思路
1.动态规划的解法:
(1)思路:具体的细节可以看LeetCode官方的解题思路,在这里我给出一个宏观的思路。首先,所有的单个元素都是回文子串,之后就是开始枚举,从长度为2 的子串开始一直枚举到字符串的长度为止。在每一次枚举的时候需要dp[i][j]来表示s{i…j}是回文子串。
时间复杂度:O(n^2)
空间复杂度:O(n^2).
(2)代码:
class Solution {
public String longestPalindrome(String s) {
int len = s.length();
if(len<2){
return s;
}
int maxLen = 1;
int start = 0;
//动态规划:dp[i][j] 表示S{i..j}是回文字符串
boolean[][] dp = new boolean[len][len];
//初始化,所有长度为1的子串都是回文串
for(int i=0; i<len; i++){
dp[i][i] = true;
}
char[] charArray = s.toCharArray();
//枚举子串长度,长度从2开始,到总长度为止。
for(int L=2; L<=len; L++){
for(int i=0;i<len;i++){
//因为j-i+1=L ,所以j=L+i-1
int j = L+i-1;
if(j>=len){ //当j>=len 时循环跳出
break;
}
if(charArray[i] != charArray[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]==true && j-i+1>maxLen){ //更新最大子串长度
maxLen = j-i+1;
start = i;
}
}
}
return s.substring(start,start+maxLen);
}
}
2、中心扩展法
(1)思路:不断的向外扩,分两种情况进行枚举:第一种就是相邻字符没有一样的;第二种情况就是相邻字符有一样的。
(2)代码
class Solution {
public String longestPalindrome(String s) {
if (s.length()<1 || s==null){
return null;
}
int start = 0;
int end = 0;
int maxLen = 1;
for(int i=0;i<s.length();i++){
int len1 = expendAroundCenter(s,i,i); //单个
int len2 = expendAroundCenter(s,i,i+1); //相邻两个相等的情况
int len = Math.max(len1,len2);
if(maxLen<len){
maxLen = len;
start = i-(len-1)/2;
end = i + len/2;
}
}
return s.substring(start,end+1);
}
public int expendAroundCenter(String s,int left,int right){
while(left>=0 && right<s.length() && s.charAt(left)==s.charAt(right)){
right++;
left--;
}
return right-left-1; //注意返回的是right--left+1-2;
}
}