[题目描述] 给出一个字符串(假设长度最长为 1000 ),求出它的最长回文子串,你可以假定只有一个满足条件的最长回文串。
在线评测地址: https://www.lintcode.com/problem/longest-palindromic-substring/?utm_source=sc-v2ex-fks0521
[样例] 样例 1:
输入:"abcdzdcab"
输出:"cdzdc"
样例 2:
输入:"aba"
输出:"aba"
[题解]
解法一: 基于中心点枚举的算法,时间复杂度 O(n^2)
public class Solution {
public String longestPalindrome(String s) {
if (s == null || s.length() == 0) {
return "";
}
int start = 0, len = 0, longest = 0;
for (int i = 0; i < s.length(); i++) {
len = findLongestPalindromeFrom(s, i, i);
if (len > longest) {
longest = len;
start = i - len / 2;
}
len = findLongestPalindromeFrom(s, i, i + 1);
if (len > longest) {
longest = len;
start = i - len / 2 + 1;
}
}
return s.substring(start, start + longest);
}
private int findLongestPalindromeFrom(String s, int left, int right) {
int len = 0;
while (left >= 0 && right < s.length()) {
if (s.charAt(left) != s.charAt(right)) {
break;
}
len += left == right ? 1 : 2;
left--;
right++;
}
return len;
}
}
解法二: 使用 Manancher's Algorithm,可以在 O(n) 的时间内解决问题
public class Solution {
public String longestPalindrome(String s) {
if (s == null || s.length() == 0) {
return "";
}
// abc => #a#b#c#
String str = generateString(s);
int[] palindrome = new int[str.length()];
int mid = 0, longest = 1;
palindrome[0] = 1;
for (int i = 1; i < str.length(); i++) {
int len = 1;
if (mid + longest > i) {
int mirrorOfI = mid - (i - mid);
len = Math.min(palindrome[mirrorOfI], mid + longest - i);
}
while (i + len < str.length() && i - len >= 0) {
if (str.charAt(i - len) != str.charAt(i + len)) {
break;
}
len++;
}
if (len > longest) {
longest = len;
mid = i;
}
palindrome[i] = len;
}
longest = longest - 1; // remove the extra #
int start = (mid - 1) / 2 - (longest - 1) / 2;
return s.substring(start, start + longest);
}
private String generateString(String s) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
sb.append('#');
sb.append(s.charAt(i));
}
sb.append('#');
return sb.toString();
}
}
[更多解法可参考] https://www.jiuzhang.com/solution/longest-palindromic-substring/?utm_source=sc-v2ex-fks0521
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.