-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathLongestPalindromeSubstring.java
More file actions
93 lines (82 loc) · 3.39 KB
/
LongestPalindromeSubstring.java
File metadata and controls
93 lines (82 loc) · 3.39 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
package datastructure.string;
/**
* Longest palindromic substring using manacher's algorithm </br>
* </br>
* <b>Manacher's algorithm</br>
* </b> Suppose we found a substring using center expansion method then we can
* find the length of palindromes for the mirror center's palindrome. we need to
* keep three things in mind:
* <ol>
* <li>if length exceeds beyond left boundary then palindrome's length at right
* part is - index of right boundary - index of palindrome's center.
* <li>if length is same then right side's palindrome's length will be the same
* as left side's palindrome
* <li>if length exceeds beyond right boundary then palindrome's length at right
* side is at least the length of left side. We can expand after that to check
* if the palindrom's length is more or not.
* </ol>
*
* youtube link :
* https://www.youtube.com/watch?v=nbTSfrEfo6M&list=PLamzFoFxwoNjPfxzaWqs7cZGsPYy0x_gI&index=4
*
* @author saukedia1
*
*/
public class LongestPalindromeSubstring {
public static void main(String[] args) {
String src = "xyzaaaghfababjhgbbbb";
System.out.println(getlongestPalindromeLength(src));
}
public static String getlongestPalindromeLength(String source) {
char[] charArray = getModifiedCharArray(source);
int[] palindromeLengthTracker = new int[charArray.length];
int center = 0;
int rightBoundary = 0;
for (int currentPosition = 1; currentPosition < charArray.length - 1; currentPosition++) {
// get the mirror location
int mirr = 2 * center - currentPosition;
// update the palindrome's length for current location from valid mirror
// location as per manacher's algorithm the current location's palindrome length
// will be at least equal to the mirror location
if (currentPosition < rightBoundary) {
palindromeLengthTracker[currentPosition] = Math.min(rightBoundary - currentPosition,
palindromeLengthTracker[mirr]);
}
// expand to check to if the palindrome's length extends
while (charArray[currentPosition + (palindromeLengthTracker[currentPosition] + 1)]
== charArray[currentPosition - (palindromeLengthTracker[currentPosition] + 1)]) {
palindromeLengthTracker[currentPosition]++;
}
// update right boundary and center
if ((currentPosition + palindromeLengthTracker[currentPosition]) > rightBoundary) {
center = currentPosition;
rightBoundary = currentPosition + palindromeLengthTracker[currentPosition];
}
}
// take the longest palindrome from palindrome tracker
int length = 0;
for (int i = 0; i < palindromeLengthTracker.length; i++) {
if (palindromeLengthTracker[i] > length) {
length = palindromeLengthTracker[i];
center = i;
}
}
return source.substring((center - 1 - palindromeLengthTracker[center]) / 2,
(center - 1 + palindromeLengthTracker[center]) / 2);
}
private static char[] getModifiedCharArray(String source) {
char[] srcCharArray = source.toCharArray();
char[] tgtCharArray = new char[(srcCharArray.length * 2) + 3];
// set terminal characters
tgtCharArray[0] = '$';
tgtCharArray[tgtCharArray.length - 1] = '@';
// set one additional symbol char at each index
for (int i = 1, j = 0; i < tgtCharArray.length - 1; i++) {
if (i % 2 == 0 && j < srcCharArray.length)
tgtCharArray[i] = srcCharArray[j++];
else
tgtCharArray[i] = '#';
}
return tgtCharArray;
}
}