LeetCode 5.最长回文子串
我觉得还是中心扩散好,运行快,代码也好理解。
中心扩散思想:
遍历整个字符串数组,每个字符都尝试向两边扩散,看两边字符是否相等,相等则继续向两边扩散;不相等则查看下一个字符。
substring(a,b),包括a,不包括b。前闭后开区间,所以最终走到a前面,b后面,a多向前走了一步,所以要start+1往后走。
中心扩散
class Solution {
//记录前后两个下标的数组rang
int [] rang = new int[2];
public String longestPalindrome(String s) {
int n = s.length();
if(n == 0 || n == 1)
return s;
//字符串转化为字符串数组
char[]ss = s.toCharArray();
//每个字符都试一次
for(int i = 1;i < n ; i++)
{//两种情况
helper(ss,n,i,i);//回文子串单数
helper(ss,n,i-1,i);//回文子串双数,中心是cc,第一个c是i-1,第二个c是i
}
//返回值:字符串的子字符串,截取字符串a-b的子串
return s.substring(rang[0],rang[1]);
}
//中心扩散
//两个辅助变量,start,end,都从中间开始向两边走。
public void helper(char []ss , int n , int start , int end){
while(start >= 0 && end<=n-1)
{
if (ss[start] == ss[end])
{
start--;
end++;
}
else
break;
}
if(end-(start+1)>rang[1]-rang[0])
{
rang[0]=start+1;
rang[1]=end;
}
}
}
动态规划
class Solution {
public String longestPalindrome(String s) {
int len = s.length();
if (len < 2){
return s;
}
int maxlen = 1;
int start = 0;
boolean[][] dp = new boolean[len][len];
char[] ss = s.toCharArray();
for (int i = 0; i < len; i++)
{
dp[i][i] = true;
}
for (int j = 1; j < len; j++){
for (int i = 0; i < j; i++){
if (ss[i] != ss[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;
start = i;
}
}
}
return s.substring(start, start + maxlen);
}
}