一、Description
Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000.
题目大意:
给定一个字符串s,求其中最长的一个回文串。回文串即正着看反着看都是一样的字符串,比如"abcba"、"aaa"...
二、Analyzation
暴力解法(过了100个样例,还有3个样例因为超时没过):
public String longestPalindrome(String s) {
if(s == null || s.length() == 0){
return "";
}
if(s.length() == 1)
return s;
int max = 0;
String result = "";
for(int i = 0;i < s.length() - 1;i++){
for(int j = i + 1;j <= s.length();j++){
String temp = s.substring(i,j);
if(temp.length() > max && isPalindromic(temp)){
max = temp.length();
result = temp;
}
}
}
return result;
}
public boolean isPalindromic(String str){
boolean flag = true;
for(int i = 0,j = str.length() - 1;i <= j;i++,j--){
if(str.charAt(i) != str.charAt(j)){
flag = false;
break;
}
}
if(flag)
return true;
else
return false;
}
dp解法:
设定一个数组dp[][],当dp[i][j] = 1时,表示字符串中从i到j的位置这一子串是回文串。
相关代码的注释已给出,如下所示。
值得注意的是,在列举回文串>=3的情形中,for循环中判断语句的意思是,如果s.charAt(i) == s.charAt(j)(子串的首尾字符相等),并且dp[i + 1][j - 1] == 1(该子串中间的子串即从i + 1到j - 1的位置是回文串),那么该子串也是回文串,即dp[i][j] = 1。
三、Accepted code
public static String longestPalindrome(String s) {
if(s == null || s.length() == 0){
return "";
}
int length = s.length();
int begin = 0,max = 1;
int[][] dp = new int[length][length];
for(int i = 0;i < length;i++) dp[i][i] = 1; //每一个单独的字符自然算一个回文串
for(int i = 0;i < length - 1;i++){ //连续两个相同字符的字符串也是一个回文串
if(s.charAt(i) == s.charAt(i + 1)){
dp[i][i + 1] = 1;
max = 2;
begin = i;
}
}
for(int len = 3;len <= length;len++){ //列举回文串长度>=3的情况
for(int i = 0;i < length - len + 1;i++){ //当前子串起始位置
int j = i + len - 1; //j - i = len - 1
if(s.charAt(i) == s.charAt(j) && dp[i + 1][j - 1] == 1){
dp[i][j] = 1;
begin = i;
max = len;
}
}
}
return s.substring(begin,begin + max);
}