214. Shortest Palindrome
来源:互联网 发布:应聘数据分析师面试题 编辑:程序博客网 时间:2024/05/20 11:21
题意: Given a string S, you are allowed to convert it to a palindrome by adding characters in front of it. Find and return the shortest palindrome you can find by performing this transformation.
For example:
Given “aacecaaa”, return “aaacecaaa”.
Given “abcd”, return “dcbabcd”.
思路:这题一开始考虑错了,以为是在任意位置添加字幕,我当时想,我靠,这怎么做啊,然后才发现是在头部添加就可以了,首先讲一种利用Manacher’s Algorithm方法的解法,本来这个算法就是用来找最长回文子串的,而且其实这道题的目的就是找到最左侧回文子串的右边界,然后把右边剩下的部分反转之后加到左边来,比如对于”babad”,最左侧的“bab”就是最左侧回文子串,再把剩下的“ad”反过来加到开头构成“dababad”,再举个栗子:“ccababa”,最左侧的回文串是“cc”,把剩下的“ababa”反转之后加到开头即可,所以有了下面的代码:
class Solution(object): def shortestPalindrome(self, s): T = ['#'] for i in s: T += ['#', i] T += ['#', '$'] mx, id = 0, 0 P = [0] * len(T) for i in xrange(1, len(T)-1): if mx > i: P[i] = min(P[2 * id - i], mx-i) else: P[i] = 1 while T[i + P[i]] == T[i - P[i]]: P[i] += 1 if i+P[i] > mx: mx = i + P[i] id = i max, max_idx = 0, 0 for i in xrange(1,len(T)-1): if i-P[i] == 0: max_len = P[i]-1 return s[len(s)-1:max_len-1:-1]+s
除了这种方法之外,还可以使用KMP来解,但是有个问题了,KMP如何找到一个字符串的最左回文的最右边界呢,比如对于一个串“aabba”,计算KMP的next数组为“-1,0,-1,-1,0”,这个完全没有头绪好吗,其实KMP算法求next的本质就是在整个串中标识出和初始位相同的串,所以如果把字串和它的反转字串合并呢?还是对于“aabba”,“aabba”+“abbaa”=“aabbaabbaa”,next数组为“-1,0,-1,-1,0,1,2,3,4,5”,如果开头几位和末尾几位相同,说明开头的几位就是回文了,而next数组的最后一位就表明了最左回文的最右边界,所以最左回文就是“aabbaa”,这里由于新构成的整个串比较独特,这个next[-1]=5超过了初始串“aabba”的长度,所以要i=next[i]=next[5]=1一下,所以新的边界就是next+1=2,这么说可能不好理解,这里还有一个更简单的方法,就是再构成新串的时候在中间加一个”#”,用来断开两个字符串,这样就不会出现next数组的值超过原始串长度的问题了,比如“aabba”+“#”+“abbaa”=“aabba#abbaa”,next数组为“-1,0,-1,-1,0,-1,0,-1,-1,0,1”,最右边界就是next[-1]+1=2,下面是”#”构造串的方法的代码:
class Solution(object): def shortestPalindrome(self, s): """ :type s: str :rtype: str """ def getPrefix(pattern): prefix = [-1] * len(pattern) j = -1 for i in xrange(1, len(pattern)): while j > -1 and pattern[j+1] != pattern[i]: j = prefix[j] if pattern[j+1] == pattern[i]: j += 1 prefix[i] = j return prefix if not s: return s A = s +"#" + s[::-1] prefix = getPrefix(A) i = prefix[-1] return s[i+1:][::-1] + s
当然不用“#”来构建串也是可以的:
class Solution(object): def shortestPalindrome(self, s): """ :type s: str :rtype: str """ def getPrefix(pattern): prefix = [-1] * len(pattern) j = -1 for i in xrange(1, len(pattern)): while j > -1 and pattern[j+1] != pattern[i]: j = prefix[j] if pattern[j+1] == pattern[i]: j += 1 prefix[i] = j return prefix if not s: return s A = s + s[::-1] prefix = getPrefix(A) i = prefix[-1] if i >= len(s): i = prefix[i] return s[i+1:][::-1] + s
- [leetcode] 214.Shortest Palindrome
- LeetCode 214. Shortest Palindrome
- leetcode 214. Shortest Palindrome
- LeetCode 214. Shortest Palindrome
- LeetCode 214. Shortest Palindrome
- leetcode.214. Shortest Palindrome
- 214. Shortest Palindrome
- 214. Shortest Palindrome
- 214. Shortest Palindrome
- 214. Shortest Palindrome(KMP)
- 214. Shortest Palindrome
- 214. Shortest Palindrome
- leetcode-214. Shortest Palindrome
- 214. Shortest Palindrome
- 【LeetCode】214. Shortest Palindrome
- 214. Shortest Palindrome
- [LeetCode]214. Shortest Palindrome
- Leetcode 214. Shortest Palindrome
- 使用xshell来操作服务器
- 在JS原型prototype中编写提取整数和移除字符串首尾空白的trim方法
- CentOS7 从零开始搭建 Hadoop2.7集群
- jQuery基础入门(一)
- 呃呃
- 214. Shortest Palindrome
- 深入理解C#:编程技巧总结(一)
- js中关于事件处理函数名后面是否带括号的问题
- 索引合并和组合索引的比较
- 文章标题
- 如何解决Chrome无法打开应用商店
- Solr学习(一)
- Docker之Hadoop普通集群搭建(五)
- 分组交换网络时延、丢包、吞吐量