-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path214. Shortest Palindrome.cpp
74 lines (67 loc) · 2.36 KB
/
214. Shortest Palindrome.cpp
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
class Solution {
public:
string shortestPalindrome(string s) {
// the response and an edge case
string res;
int oriSz = s.size();
if (oriSz == 0) return res;
res.reserve(2*oriSz);
// stuffing
string stuffedStr;
int stuffedSz = 2*oriSz + 3;
stuffedStr.reserve(stuffedSz);
stuffedStr += '$';
for (int i = 0; i < oriSz; i++) { // char s[i]
stuffedStr += '#';
stuffedStr += s[i];
}
stuffedStr += '#';
stuffedStr += '^';
//
// Manacher's algorithm; customized
//
int *radii = new int[stuffedSz];
radii[0] = 1;
int globalPivot = 0;
for (int currPivot = 1; currPivot < stuffedSz; currPivot++) {
// calculate radii[currPivot]
int& currRadius = radii[currPivot];
int globalEnd = globalPivot + radii[globalPivot]; // exclusive
if (currPivot < globalEnd) {
int diff = globalEnd - currPivot;
int radiusSymmPt = radii[2*globalPivot - currPivot];
currRadius = diff < radiusSymmPt ? diff : radiusSymmPt;
}
else {
currRadius = 1;
}
while (stuffedStr[currPivot-currRadius] == stuffedStr[currPivot+currRadius]) currRadius++;
// update globalPivot
int currEnd = currPivot + currRadius; // exclusive
if (currEnd > globalEnd) {
globalPivot = currPivot;
}
}
// go over radii[] and find the required window: longest and starting from 1
int longestRadius = -1;
int pivotWanted = -1;
for (int i = 1; i < stuffedSz/2 + 1; i++) { // pivot i
int stt = i - radii[i] + 1; // inclusive
if (stt == 1) {
if (radii[i] > longestRadius) {
longestRadius = radii[i];
pivotWanted = i;
}
}
}
// find the wanted palindrome substring in the original string s
int iLast = radii[pivotWanted] - 2;
// delete[] radii;
// get the response
for (int i = oriSz - 1; i > iLast; i--) { // char s[i]
res += s[i];
}
res += s;
return res;
}
};