题目描述
Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000.
Example 1:
- Input: “babad”
- Output: “bab”
Note: “aba” is also a valid answer.
Example 2:
- Input: “cbbd”
- Output: “bb”
AC代码1
这种方法很好理解,时间复杂度为 O(n * n)
参考自:
https://leetcode.com/problems/longest-palindromic-substring/discuss/2928/Very-simple-clean-java-solution
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++) {
//因为回文序列有奇(aba)、偶(abba),两种形式。奇数回文序列从最中间的数字开始向两边尽量延伸和拓展,而偶数回文序列从最中间的两个数字开始尽可能的向两边拓展。
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;
}
}}
AC代码2
时间复杂度和空间复杂度都为 O(n),统一处理了奇数回文子串和偶数回文子串
Manacher’s Algorithm (马拉车算法)
参考自:
https://www.cnblogs.com/grandyang/p/4475985.html (这篇文章里面说了为什么要在开头额外加上一个其他字符)
https://articles.leetcode.com/longest-palindromic-substring-part-ii/
https://www.felix021.com/blog/read.php?2040
class Solution {
public:
string longestPalindrome(string s) {
string t ="$#";
for (int i = 0; i < s.size(); ++i) {
t += s[i];
t += '#';
}
int p[t.size()] = {0}, id = 0, mx = 0, resId = 0, resMx = 0;
for (int i = 0; i < t.size(); ++i) {
p[i] = mx > i ? min(p[2 * id - i], mx - i) : 1;
while (t[i + p[i]] == t[i - p[i]]) ++p[i];
if (mx < i + p[i]) {
mx = i + p[i];
id = i;
}
if (resMx < p[i]) {
resMx = p[i];
resId = i;
}
}
return s.substr((resId - resMx) / 2, resMx - 1);
}
};
参考资料:
https://www.cnblogs.com/grandyang/p/4464476.html
https://articles.leetcode.com/longest-palindromic-substring-part-i/