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算法来解这题。

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的更多相关文章

  1. [Swift]LeetCode214. 最短回文串 | Shortest Palindrome

    Given a string s, you are allowed to convert it to a palindrome by adding characters in front of it. ...

  2. [LeetCode] Shortest Palindrome 最短回文串

    Given a string S, you are allowed to convert it to a palindrome by adding characters in front of it. ...

  3. LeetCode 214 Shortest Palindrome

    214-Shortest Palindrome Given a string S, you are allowed to convert it to a palindrome by adding ch ...

  4. Shortest Palindrome

    Given a string S, you are allowed to convert it to a palindrome by adding characters in front of it. ...

  5. 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. ...

  6. 【leetcode】Shortest Palindrome(hard)★

    Given a string S, you are allowed to convert it to a palindrome by adding characters in front of it. ...

  7. LeetCode Shortest Palindrome

    原题链接在这里:https://leetcode.com/problems/shortest-palindrome/ 题目: Given a string S, you are allowed to ...

  8. 214. Shortest Palindrome

    题目: Given a string S, you are allowed to convert it to a palindrome by adding characters in front of ...

  9. 【Leetcode】Shortest Palindrome

    Shortest Palindrome Given a string S, you are allowed to convert it to a palindrome by adding charac ...

随机推荐

  1. ContestHunter暑假欢乐赛 SRM 09(TJM大傻逼选手再创佳绩)

    T1 f[i]为前i页最少被撕几页,用二分转移就行了,答案为ans=min(f[i]+(n-i)); 不知道为什么写挂了嗯 二分的l初始应该是0 T2 数位DP f[i][1/0][1/0][1/0] ...

  2. HDU 4549 矩阵快速幂+快速幂+欧拉函数

    M斐波那契数列 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Sub ...

  3. ContentProvider学习

    1.创建类继承ContentProvider类,并实现增.删.改.查功能. public static final String AUTHORITY = "com.diysoul.lists ...

  4. ACM1881 01背包问题应用

    01背包问题动态规划应用 acm1881毕业bg 将必须离开的时间限制看作背包容量,先将他们由小到大排序,然后在排完序的数组中对每个实例都从它的时间限制开始(背包容量)到它的延长时间进行遍历: #in ...

  5. github访问速度慢,样式加载不完全解决

    现象如下图: 解决方案: 绑定host 185.31.17.184 github.global.ssl.fastly.net

  6. Jade模板引擎学习(一)安装及基本语法

    Jade是一款高性能简洁易懂的模板引擎,Jade是Html的Javascript实现,在服务端(NodeJS)及客户端均有支持. 一.功能 客户端支持  超强的可读性 灵活易用的缩进 块扩展 代码默认 ...

  7. Zyan 一个通信框架

    原文地址 本文示例 Zyan是一个简单直观的分布式应用程序开发框架. 以下是Zyan项目的简要概述. 架构图: Zyan一般由客户端和服务端组成.服务端(以组件的形式)提供服务,客户端远程调用服务端的 ...

  8. VM 脚本回快照和开关机

    #Import PowerCLI*Get-Module -ListAvailable PowerCLI* | Import-Module #Resolve login issueSet-PowerCL ...

  9. Jmeter-7-在命令行中运行Jmeter.

    jmeter -n -t D:\Jmeter_result\Script_baidu.jmx -l D:\Jmeter_result\Script_baidu.txt jmeter -n -t D:\ ...

  10. 基于FPGA的HDTV视频图像灰度直方图统计算法设计

    随着HDTV的普及,以LCD-TV为主的高清数字电视逐渐进入蓬勃发展时期.与传统CRT电视不同的是,这些高清数字电视需要较复杂的视频处理电路来驱动,比如:模数转换(A/D Converter).去隔行 ...