题目
Example 1:
Input: s = "babad"
Output: "bab"
Note: "aba" is also a valid answer.
Example 2:
Input: s = "cbbd"
Output: "bb"
Example 3:
Input: s = "a"
Output: "a"
Example 4:
Input: s = "ac"
Output: "a"
Constraints:
1 <= s.length <= 1000
s
consist of only digits and English letters (lower-case and/or upper-case)
解法一
思路是从头开始遍历该字符串,看每一个字符串向前后扩展,所能形成的最长回文字符串长度是多少。有一点麻烦的是回文串有两种,一种是奇数的(aba),一种是偶数的(abba)。这两种情况要分别考虑。我自己的代码也是这种思路做的,有点啰嗦,把高赞评论里的贴出来。
public class Solution {
private int lo, maxLen;
public String longestPalindrome(String s) {
int len = s.length();
if (len < 2)
return s;
for (int i = 0; i < len-1; i++) {
extendPalindrome(s, i, i); //assume odd length, try to extend Palindrome as possible
extendPalindrome(s, i, i+1); //assume even length.
}
return s.substring(lo, lo + maxLen);
}
private void extendPalindrome(String s, int j, int k) {
while (j >= 0 && k < s.length() && s.charAt(j) == s.charAt(k)) {
j--;
k++;
}
if (maxLen < k - j - 1) {
lo = j + 1;
maxLen = k - j - 1;
}
}}
解法二:
另一种思路有点类似递归,就是如果字符串***是回文字符串,意味着首尾各加上一个相同字符后也是递归,对应奇数个数的回文串。或者两位长度的子字符串,且这两位字符相同,则为递归,且按照首尾各加一个相同字符的方式扩展后也是递归,对应偶数个数的回文串。
如下解法中i代表子字符串左起点;j代表子字符串右起点。
class Solution {
public String longestPalindrome(String s) {
if (s == null || s.length() <= 1)
return s;
int len = s.length();
// dp[i][j] stands for status of a substring starting at i and ending at j incl j
boolean[][] dp = new boolean[len][len];
// initialize all the 1 character palins
for(int i = 0; i < len; i++)
dp[i][i] = true;
// to compute dp[i][j] we need dp[i+1][j-1]
// so the i - outer loop needs to go from higher to lower
// and the j - inner loop needs to go from lower to higher
int maxLen = 0, maxSta = 0, maxEnd = 0;
for(int i = len; i >= 0; i--){
// dist of 0 - already covered by initialization
for(int dist = 1; dist < len - i; dist++){
int j = i + dist;
// we are ready to compute dp [i] [j]
if (dist == 1 && s.charAt(i) == s.charAt(j)){
dp[i][j] = true;
} else if (s.charAt(i) == s.charAt(j)){
dp[i][j] = dp[i+1][j-1];
}
// if true
if (dp[i][j] && maxLen < (j-i+1)){
maxLen = j - i + 1;
maxSta = i;
maxEnd = j;
}
}
}
return s.substring(maxSta,maxEnd+1);
}
}