Given a string S, find the longest palindromic substring in S. You may assume that the maximum length of S is 1000, and there exists one unique longest palindromic substring.

方法一:(递归:超时)

假设X[0,1,...,n-1]是给定的序列,L[0,n-1]表示序列X的最大回文子序列的长度。

当首尾字符相同时,L[0,n-1]=L[1,n-2]+2;

当首尾字符不同时,L[0,n-1]=max{L[1,n-1],L[0,n-2]}

public class Solution {
public int longestPalindromeSubseq(String s) {
return lps(s,0,s.length()-1);
}
int lps(String s,int i,int j)
{
if(i==j)
return 1;

int temp=0;
if(i<j)
{
if(s.charAt(i)==s.charAt(j))
temp=lps(s,i+1,j-1)+2;
else
{
temp=Math.max(lps(s,i+1,j),lps(s,i,j-1));
}
}
return temp;
}
}

 方法二:(动态规划)

方法一中存在重复计算,即存在重叠子问题

public class Solution {
    public int longestPalindromeSubseq(String s) {
    int[][] p=new int[s.length()][s.length()];
    for(int i=0;i<s.length();i++)
        p[i][i]=1;
    for(int i=1;i<s.length();i++)
    {
        for(int j=0;i+j<s.length();j++)
        {
            int temp=0;
            if(s.charAt(j)==s.charAt(i+j))//首尾相同时
            {
                p[j][j+i]=p[j+1][j+i-1]+2;
            }
            else
            {
                p[j][j+i]=Math.max(p[j+1][j+i],p[j][j+i-1]);//首尾不同时
            }
            
        }
    }
    return p[0][s.length()-1];
    }
    
}

方法三:(逆串+LCS)

a.求字符串你传

b.求子串与逆串的最长公共子序列(LCS)

public class Solution {
    public int longestPalindromeSubseq(String s) {
    char[] str1=s.toCharArray();
    char[] str2=new char[s.length()];
    int[][] p=new int[s.length()+1][s.length()+1];
    for(int i=0;i<s.length();i++)
        str2[i]=str1[s.length()-1-i];
    p[0][0]=0;   
    for(int i=1;i<=s.length();i++)
    {
        for(int j=1;j<=s.length();j++)
        {
            if(str1[i-1]==str2[j-1]) 
                p[i][j]=p[i-1][j-1]+1;
            else
                p[i][j]=Math.max(p[i-1][j],p[i][j-1]);
        }
    }
    
    return p[s.length()][s.length()];
    }
    
}