LeetCode-005-最长回文子串
思路
方法一:动态规划
- 定义状态:dp[i][j]表示字符串s[i…j]是否为回文
- 状态转移方程 dp[i][j]=dp[i+1][j-1]&&s[i]==s[j]
- 三种情况
//头尾不等直接false
if(arr[i]!=arr[j])dp[i][j]=false;
else{
//中间长度小于等于1,直接true
if(j-i<3)dp[i][j]=true;
//否则,只需看中间子串是否回文
else dp[i][j]=dp[i+1][j-1];
}
方法二:中心扩散
以1个或者2个字符为中心向外扩散,判断是否满足回文
代码
//方法一
class Solution {
public String longestPalindrome(String s) {
int len=s.length();
//长度小于等于1,直接返回字符串本身
if(len<2)return s;
char []arr=s.toCharArray();
boolean [][]dp=new boolean[len][len];
//每个字符必定是回文
for(int i=0;i<len;i++){
dp[i][i]=true;
}
//j为右边界,i为左边界
for(int j=1;j<len;j++){
for(int i=0;i<j;i++){
//头尾不等直接false
if(arr[i]!=arr[j])dp[i][j]=false;
else{
//中间长度小于等于1,直接true
if(j-i<3)dp[i][j]=true;
//否则,只需看中间子串是否回文
else dp[i][j]=dp[i+1][j-1];
}
}
}
int max=0;
int begin=0;
for(int i=0;i<len;i++){
for(int j=0;j<len;j++){
if(dp[i][j]&&max<j-i+1){
max=j-i+1;
begin=i;
}
}
}
return s.substring(begin,begin+max);
}
}
//方法二
class Solution {
public String longestPalindrome(String s) {
int l=0,r=0;
for(int i=0;i<s.length();i++){
int odd=check(s,i,i);
int even=check(s,i,i+1);
int len=Math.max(odd,even);
if(len>(r-l+1)){
r=i+len/2;
l=r-len+1;
}
}
return s.substring(l,r+1);
}
public int check(String s,int left,int right){
while(left>=0&&right<s.length()&&s.charAt(left)==s.charAt(right)){
left--;
right++;
}
return right-left-1;
}
}