code:
func longestPalindrome(s string) string {
nLen := len(s)
if 0 == nLen {
return ""
}
/*with no thought of those characters that have many bytes,
solve this problem using Manacher's Algorithm,
https://blog.csdn.net/sky527759/article/details/102892788,
it explains what is the Manacher's Algorithm
*/
//"babad" -> "#b#a#b#a#d#" -> "&#b#a#b#a#d#|", avoid judging out-of-array
strMaLen := nLen * 2 + 3
strManacher := make([]byte, strMaLen)
strManacher[0], strManacher[strMaLen - 2], strManacher[strMaLen - 1] = '&', '#', '|'
for i, j, endPos := 1, 0, strMaLen - 2; i < endPos; i += 2 {
strManacher[i], strManacher[i + 1] = '#', s[j]
j++
}
//fmt.Printf("nLen:%d, s:%v\n", nLen, s)
//fmt.Printf("strMaLen:%d, strManacher:%v\n", strMaLen, string(strManacher))
//return ""
//accomplish Manacher's Algorithm
//according TGPL, anManacher[0] ~ anManacher[strMaLen - 1] are 0 after initialization
anManacher := make([]int, strMaLen)
nMaxLen, nPos := 0, 0
nMidPos, nRightPos, nRightPosTemp := 0, 0, 0
for i, endPos := 1, strMaLen - 1; i < endPos; i++ {
if i < nRightPos {
anManacher[i] = int(math.Min(float64(anManacher[2 * nMidPos - i]), float64(nRightPos - i + 1)))
} else {
anManacher[i] = 1;
}
//fmt.Printf("i:%d\n", i)
for strManacher[i - anManacher[i]] == strManacher[i + anManacher[i]] {
anManacher[i]++
}
nRightPosTemp = i + anManacher[i] - 1
if nRightPosTemp > nRightPos {
nMidPos, nRightPos = i, nRightPosTemp
if anManacher[i] > nMaxLen {
nPos, nMaxLen = i, anManacher[i]
}
}//if nRightPosTemp > nRightPos
}//for i, endPos := 1, strMaLen - 1; i < endPos; i++
//fmt.Printf("nPos:%d, nMaxLen:%d\n", nPos, nMaxLen)
return s[(nPos - nMaxLen + 1) / 2 : (nPos + nMaxLen - 1) / 2]
}
result:
personal opinion:
The Manacher’s algorithm is so sweet, I like it !