Given A string s, find the longest palindromic substring in S. Assume that the maximum length of S is 1000.
Example:
Input: "Babad"
Output: "Bab"
Note: "ABA" is also a valid answer.
Example:
Input: "CBBD"
Output: "BB"
1. Center Expansion Method O (n*n)
You need to consider two cases of palindrome strings being odd and even
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.ch Arat (j) = = S.charat (k)) {
j--;
k++;
}
if (MaxLen < k-j-1) {
lo = j + 1;
MaxLen = k-j-1;}}}
2. Manacher
First, in a very ingenious way, all possible odd/even length palindrome strings are converted to odd lengths: a special symbol is inserted on both sides of each character. For example, Abba becomes #a #b#b#a#, ABA becomes #a #b#a#. To further reduce the complexity of the encoding, you can add another special character at the beginning of the string, so that you do not have to deal with cross-border issues specifically, such as $ #a #b#a# (note that the following code is written in C, because the C language specification also requires that the string end has a ' \ 0 ' So just OK, but other languages may cause a cross-border.
The following is an example of string 12212321, which, after the previous step, became s[] = "$ #1 #2#2#1#2#3#2#1#";
Then use an array p[i] to record the length of the left/right expansion of the longest palindrome string centered on the character S[i] (including S[i], that is, the length of "fold" the palindrome string, such as the correspondence between S and P: S # 1 # 2 # 2 # 1 # 2 # 3 # 2 # 1 #
P 1 2 1 2 5 2 1 4 1 2 1 6 1 2 1 2 1
(as you can see, P[i]-1 is exactly the total length of the palindrome string in the original P.S)
So how to calculate p[i]? The algorithm adds two helper variables (in fact one is enough, two clearer) ID and MX, where the ID is the center of the palindrome substring of the known {right bounded maximum}, and MX is id+p[id], which is the right edge of the substring.
Then you can get a very magical conclusion, the key point of this algorithm is here: if mx > I, then p[i] >= MIN (p[2 * id-i], mx-i). This is the string card I have been very long. In fact, if you write it a little more complicated, it will be easier to understand://j = 2 * id-i, that is, J is the symmetric point about ID (j = ID-(I-ID))
if (Mx-i > P[j])
P[i] = P[j];
else/* P[j] >= mx-i */
P[i] = mx-i; P[i] >= mx-i, take the minimum value, and then match the update.
Of course, the code is still not clear enough, or the use of diagrams to understand the more easily.
When Mx-i > P[j], the palindrome string centered on S[j] is contained in a palindrome string centered on S[id], because I and J are symmetric, the palindrome string centered on s[i] is necessarily contained in a palindrome string centered on S[id], so there must be p[i] = P[j], see the figure below.
When P[j] >= mx-i, the palindrome string centered on s[j] is not necessarily completely contained in a palindrome string centered on S[id], but based on symmetry, the two green boxes in the image below are surrounded by the same part, that is, the palindrome string centered on the s[i], It will expand to the right at least to the MX position, i.e. P[i] >= mx-i. As to whether the post-MX part is symmetrical, it can only be honestly matched.
For the case of MX <= i, p[i] could not be made more assumptions, only p[i] = 1, and then to match.
So the code is as follows://input, and process get string s
int p[1000], mx = 0, id = 0;
memset (p, 0, sizeof (p));
for (i = 1; s[i]! = '; i++ ") {
P[i] = mx > I? Min (P[2*id-i], mx-i): 1;
while (S[i + p[i]] = = S[i-p[i]]) p[i]++;
if (i + p[i] > mx) {
MX = i + p[i];
id = i;
}
}
Find the largest of the p[i]
Over.
Package Leetcode;
public class Solution {public String longestpalindrome (string str) {string s = "$#";//String encapsulation facilitates uniform string-length parity
for (int i = 0; i < str.length (); i++) s + = Str.charat (i) + "#"; int max = 0;//records the maximum value of the P array.
Ps:p[i]-1 is the original string in the current position letter centered palindrome string size int id = 0;//The current find position before the maximum palindrome string of the center subscript int maxindex=0;
Int[] p = new int[s.length ()];
for (int i = 0; i < s.length (); i++) {//traversal wrapper string int maxlen = P[id] + id;//Current lookup position, known to affect the rightmost string if (MaxLen > I)//current traversal element within the influence range of the previous maximum palindrome p[i] = math.min (p[2 * id-i], MaxLen
-i); while (i + P[i] < S.length () && i-p[i] >= 0//The current traversal element above the minimum length, both sides of the expansion comparison && S.char
At (i-p[i]) = = S.charat (i + p[i]) ++p[i];
if (MaxLen < i + p[i])//update the known maximum string information id = i; if (Max < P[i])
{//Retain max value information max = P[i];
Maxindex=i;
}} StringBuilder result=new StringBuilder ();
for (int i=maxindex-max+2;i<maxindex+max-1;i+=2) {result.append (S.charat (i));
} return result.tostring ();
} public static void Main (String[]args) {Solution s=new solution ();
System.out.print (S.longestpalindrome ("Babad"));
}
}