很有意思的一道题。
字符串s可以在左侧插入任意字符,求最短的新回文字符串s'
贪心策略很容易想到,找s的一个最长的回文前缀,将回文前缀后面的内容reverse放到最前
暴力o(n^2),需要o(n)选前缀,o(n)判断是否回文
优雅的做法是利用KMP,
使s'' = s + "$" + reverse(s)
则s''的失败数组中的最后一项即为s的最长回文前缀
复杂度O(N)
代码如下:
func shortestPalindrome(s string) string {
reverseStr := reverse(s)
news := s + "$" + reverseStr
n := len(news)
f := make([]int, n)
for i := 1; i < n; i++ {
t := f[i - 1]
for (t > 0 && news[i] != news[t]){
t = f[t - 1]
}
if (news[i] == news[t]){
t++
}
f[i] = t
}
return reverseStr[:len(s) - f[n - 1]] + s;
}
func reverse(s string) string{
n := len(s)
news := ""
for i := 0; i < n; i++{
news = news + string(s[n-1-i])
}
return news
}