LeetCode214. Shortest Palindrome
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.
Example 1:
Input:"aacecaaa"
Output:"aaacecaaa"
Example 2:
Input:"abcd"
Output:"dcbabcd"
思路
最简单直接的方法是 brute force,即先求以起始索引为开始位的最长回文字串,然后将剩下的部分逆置直接加到s前即可。这种方法比较耗时,可以使用KMP算法来解这题。
将s和其逆转字符串r连接起来,这肯定是一个回文,在他们中间加一个其它字符构成新的字符串t,然后还需要一个和t长度相同的一位数组next,其中next[i]表示从t[i]到开头的子串的相同前缀后缀的个数,就是KMP算法中的那个next数组。最后把不相同的个数对应的字符串添加到s之前即可。其实和brute force一样都是找以起始索引为开始位的最长回文字串,只不过现在不是遍历各个字符去找,而是利用KMP算法去找。找到后直接将原字符串s除了这个回文字串剩下的部分逆置后加到s前面即可。
下面next数组的计算过程可以参照KMP算法解释连接中最大长度表部分。
对于next[i-1],加入索引i位置上的字符得到的0~i的字串情况next[i]是如何变化的呢?原来的所有前缀不变,但是多了个前缀,即原来的最长前缀加上i-1位置上的的字符。原来的后缀都要发生变化,因为最后面的字符改掉了,所以原来的所有后缀要加上i位置上的字符,另外还多出了一个后缀,即位置i上的单个字符。

如果next[i-1]是0,即没有匹配的前后缀,那么加上位置i上的字符后前缀后缀也是不匹配的。但是有一种可能会增加前缀后缀的公共最长元素,那就是原来的起始索引处的字符可能等于新加入的i索引位置上的字符,若相等则next[i]=1,否则还是0。
假如next[i-1]不是0,则其值是0到索引i-1位置上的字串中前缀后缀的最大公共元素长度(能够匹配的最长前缀后缀,且注意前缀一直是从0开始的,这样的话最长前缀加上其长度就是其在前后缀比较过程中不匹配的字符索引位置)。
next[i] -- 0~i处匹配的最长前缀后缀的长度。
代码
public String shortestPalindrome(String s) {
String temp = s + "#" + new StringBuilder(s).reverse().toString();
int[] table = getTable(temp);
//get the maximum palin part in s starts from 0
return new StringBuilder(s.substring(table[table.length - 1])).reverse().toString() + s;
}
public int[] getTable(String s){
//get lookup table
int[] table = new int[s.length()];
//pointer that points to matched char in prefix part
int index = 0;
//skip index 0, we will not match a string with itself
for(int i = 1; i < s.length(); i++){
if(s.charAt(index) == s.charAt(i)){ //一开始i=1,index=0,比较s[0]和s[1],如果相等那么table[1]=1,index=1
//we can extend match in prefix and postfix
table[i] = table[i-1] + 1; //
index ++;
}else{
//因为index指向table[i-1]的最长匹配前缀的末位置字符,如果这个字符不等于位置i上的字符则断定原来的最长前缀肯定不匹配任何后缀(因为后缀以末字符为尾)
//假设原来的最长匹配前缀是s[0~2],那么可以得出s[0~3],s[0~4]这些比最长匹配前缀要长的前缀肯定是不匹配后缀的,而新的后缀无非就是后面加了个字符,
//那么这些前缀肯定也不能匹配新的后缀,但是如果原来i-1位置上的字符等于i位置上的字符而index这时指向的是i-1位,则便是上面if的情形
//table[i]表示在s[0~i]中匹配的最长前缀的末字符位置,如果table[5]=2则表示s[0~5]中匹配的最长前缀是s[0~2],让index来指向这个末位置字符。
index = table[i-1];
while(index > 0 && s.charAt(index) != s.charAt(i)){
//we will try to shorten the match string length until we revert to the beginning of match (index 1)
index = table[index-1];
}
//when we are here may either found a match char or we reach the boundary and still no luck
//so we need check char match
if(s.charAt(index) == s.charAt(i)){
//if match, then extend one char
index ++ ;
}
table[i] = index;
}
}
return table;
}
LeetCode214. Shortest Palindrome的更多相关文章
- [Swift]LeetCode214. 最短回文串 | Shortest Palindrome
Given a string s, you are allowed to convert it to a palindrome by adding characters in front of it. ...
- [LeetCode] Shortest Palindrome 最短回文串
Given a string S, you are allowed to convert it to a palindrome by adding characters in front of it. ...
- LeetCode 214 Shortest Palindrome
214-Shortest Palindrome Given a string S, you are allowed to convert it to a palindrome by adding ch ...
- Shortest Palindrome
Given a string S, you are allowed to convert it to a palindrome by adding characters in front of it. ...
- Java for LeetCode 214 Shortest Palindrome
Given a string S, you are allowed to convert it to a palindrome by adding characters in front of it. ...
- 【leetcode】Shortest Palindrome(hard)★
Given a string S, you are allowed to convert it to a palindrome by adding characters in front of it. ...
- LeetCode Shortest Palindrome
原题链接在这里:https://leetcode.com/problems/shortest-palindrome/ 题目: Given a string S, you are allowed to ...
- 214. Shortest Palindrome
题目: Given a string S, you are allowed to convert it to a palindrome by adding characters in front of ...
- 【Leetcode】Shortest Palindrome
Shortest Palindrome Given a string S, you are allowed to convert it to a palindrome by adding charac ...
随机推荐
- UVA.136 Ugly Numbers (优先队列)
UVA.136 Ugly Numbers (优先队列) 题意分析 如果一个数字是2,3,5的倍数,那么他就叫做丑数,规定1也是丑数,现在求解第1500个丑数是多少. 既然某数字2,3,5倍均是丑数,且 ...
- 分享一个JQuery弹出层插件
JQuery插件TipsWindown 1.1 一个基于jQuery的弹出层.支持拖拽,支持内容为文字,图片,URL等!至于兼容性.在IE6下,弹出对像无法绝对固定.其他应该没啥大问题: 最新更新:( ...
- java中静态变量与静态方法的继承(转)
总结: 1.静态变量与静态方法说继承并不确切,静态方法与变量是属于类的方法与变量.而子类也属于超类,比如说Manage extends Employee,则Manage也是一个Employee,所以子 ...
- ios的hitTest方法以及不规则区域内触摸事件处理方法
概述 在正常的使用场景中,我们处理了比较多的矩形区域内触摸事件,比如UIButton.UIControl.一般来说,这些控件的图形以及触摸区域都是矩形或者圆角矩形的.但是在一些特殊应用场景中我们有时不 ...
- AIM Tech Round (Div. 2) B
B. Making a String time limit per test 1 second memory limit per test 256 megabytes input standard i ...
- Network LCA修改点权
Problem Description The ALPC company is now working on his own network system, which is connecting a ...
- window10下的solr6.1.0入门笔记之---安装部署
1.安装部署java1.6+ ,确保jre安装[安装步骤略] 安装后的环境为jdk1.8+ jre1.8+ 2.安装ant 下载:官网=>http://ant.apache.org/=> ...
- Sass 基本函数
Sass 中的常用函数 一.字符串函数 1. unquote($string): 删除字符串前后的引号,删除一对引号,如果这个字符串没有带有引号,将返回原始的字符串. 示例: .text1 { con ...
- 【NOIP】提高组2016 天天爱跑步
[题意]n个点的树,有m个人同时开始走链,每一步花一秒,n个点都有观察员在ai秒观察,求每个观察员观察到的人数. [算法]树上差分(主席树||线段树合并) [题解]一个人的走链可以拆成u-lca和lc ...
- cocos2dx 某缩放的页面 CCTableView最后一个标签无法点中
有一个二级界面,在ipad4下面放大到1.6倍,直接对最外层的CCLayer缩放的,里面包含有CCTableView.结果运行的时候无法选中到最后一个标签,无论总的标签是2个还是更多,单步调试,发现到 ...