最长回文前缀的求解【LeetCode 214】

题目描述:

给定一个字符串 s,你可以通过在字符串前面添加字符将其转换为回文串。找到并返回可以用这种方式转换的最短回文串。

示例 :
  输入:s = "aacecaaa"
  输出:"aaacecaaa"

提示:
  0 <= s.length <= 5 * 104
  s 仅由小写英文字母组成

链接:https://leetcode-cn.com/problems/shortest-palindrome/

 

分析:

最终的答案是什么样子呢?假设给s增加前缀为s1。

因为s1+s是回文的整体是回文的,所以s-s1的部分也是回文的,而添加的部分s1就是串s减去串s的最长回文前缀。

所以,这个问题就变成了如何求串s的最长回文前缀。

 

解法一:马拉车算法

马拉车算法可在O(n)时间内求出一个串的以各个位为中心的最大回文长度。

我们把串s跑一遍马拉车算法,然后找最长回文前缀的话就加个特判就好:这个回文中心 i 能扩展到第一个字符,也就是回文中心 i 的扩展长度是 i-1。

 

解法二:KMP算法

KMP算法也可以求出一个串的最长回文前缀。

next[i] 表示的就是前 i-1位的字符串的最长公共前后缀的长度。所以我们把s串倒序生成s1,然后s和s1合并,跑一遍KMP算法。

例如:串s为abacd,其倒序串s1为dcaba,合起来串为abacddcaba。可以看出其最长公共前后缀就是aba,也就是串s的最长回文前缀。

这里有特殊情况要注意,如果串s为aaa,那么其倒序串也为aaa,最终aaaaaa的最长公共前后缀5,,答案就不正确了。

所以我们在把s和s1合并的时候,中间加一个串s没有的特殊的分隔符,如#。这样出来的串是aaa#aaa,分隔符保证了其最长公共前后缀一定是在串s中。

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值