Longest Palindromic Substring

Given a string S, find the longest palindromic substring in S. You may assume that the maximum length of S is 1000, and there exists one unique longest palindromic substring.
给定一个字符串S,找到它的最长回文子字符串。可以假设,S的最大长度1000,并且存在唯一的最长字符串。

解1:

我们常有一个误区,认为一个字符串与它的逆序字符串的共有的子串,就是最长的回文字符串。在的到的子串我们应该判断相同的字符串,在原字符串的位置是不是相同。相同的话我们可以作为一个候选子串,反之,则忽略这个子串。
这种解法需要找两个字符串的相同子串,通过两层循环迭代,时间复杂度为O(n2),空间复杂度为O(n2)可优化为O(n)。关于最长相同子串,可点击这里。

解2(暴力解):

通过对一个字符串的所有子序列进行判断是不是回文序列来得出解。
这种方式时间复杂度为,全排需要两层循环,判断是不是回文需要一次循环,时间复杂度为O(n^3)。空间复杂度为O(1)。

解3(动态规划):

改进解2中不必要的迭代。我们知道如果一个回文字符串,两侧有相同的字符。


Longest Palindromic Substring_第1张图片

由上式可以得到一个table,存储回文序列的组合。下标为字符串的初始下标和结束下标。在通过table找出最大的回文子串。这种方式时间和空间复杂度都为O(n^2)。

解4(以中心延展):

而其基本字符串是a或者aa两种形式。我们可以两次循环,第一次以一个元素作为基本回文单位,向两侧延伸,相同则继续延展,直至结束条件,则返回了以这个单位为中心延展的最大回文序列。通过一个循环,即可求出最长回文字符串。代码如下(C++)
public String longestPalindrome(String s) { int start = 0, end = 0; for (int i = 0; i < s.length(); i++) { int len1 = expandAroundCenter(s, i, i); int len2 = expandAroundCenter(s, i, i + 1); int len = Math.max(len1, len2); if (len > end - start) { start = i - (len - 1) / 2; end = i + len / 2; } } return s.substring(start, end + 1); } private int expandAroundCenter(String s, int left, int right) { int L = left, R = right; while (L >= 0 && R < s.length() && s.charAt(L) == s.charAt(R)) { L--; R++; } return R - L - 1; }

解5(Manacher's Algorithm):

具体分析可点击这里
该算法经过精巧的处理,将问题转化为线性时间问题。时间复杂度为O(n),空间复杂度为O(n).

你可能感兴趣的:(Longest Palindromic Substring)