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

For example:

Given "aacecaaa", return "aaacecaaa".

Given "abcd", return "dcbabcd".

题解

转化成最大回文串

问题可以转化为求以第一个元素开始的最大回文子串,只要知道了以第一个元素开始的最大回文子串,那么只要在原字符串前面逆序插入除去以第一个元素开始的最大回文子串后剩下的元素。

昨天刚好做过最大文子串的问题,用Manacher算法可以在时间复杂度O(n)和空间复杂度O(n)内解决。用Manacher求每个元素为中心的回文串半径时,只需要求前一半即可,因为以后一一半的任意元素为中心的回文子串不可能从第一个元素开始。

string shortestPalindrome(string s) {
//Manacher求出以每个字符为中心的回文串长度
string str = "$#";
for (int i = 0; i != s.size(); ++i) {
str.push_back(s[i]);
str.push_back('#');
}
str.push_back('~');
int id = 0;
int mx = 0;
//只需要求前一半字符的p[]数组中的值。
vector<int> p(str.size() / 2 + 1);
for (int i = 1; i != p.size(); ++i) {
if (i < mx)
p[i] = mx - i < p[2 * id - i] ? mx - i : p[2 * id- i];
else
p[i] = 1;
while (str[i - p[i]] == str[i + p[i]]) ++p[i];
if (i + p[i] > mx) {
mx = i + p[i];
id = i;
}
}
int index = 0;
int len = 1;
//找出最后一个以第一个字符开始的回文串
for (int i = 1; i != p.size(); ++i) {
if ((i - p[i]) / 2 == 0) {
len = p[i];
index = i;
}
}
index = (index - len) / 2;
--len;
//生成最终结果的回文串
string result;
for (int i = s.size() - 1; i >= index + len; --i) result.push_back(s[i]);
result += s;
return result;
}

利用KMP求next数组的方法

解决该问题可以转化成寻找以第一个元素开始的最大的回文子串。

我们知道回文串的逆序串等于它本身,记字符串为str,逆串为reverse,以第一个元素开始的最大的回文子串将匹配到reverse的后缀,如果把令str+reverse称为新串,则有最大匹配的前缀和后缀的长度是以第一个元素开始的最大回文子串。KMP算法中的next数组保存的就是该元素之前的子串的最大匹配前缀和后缀的长度,我们就可以利用该算法来求解该问题。

KMP算法中的next数组是包括整串的最大匹配前缀和后缀的长度,所以解决该问题的next需要比KMP的next大1,最终next[strlen(str+reverse)]就是第一个元素开始的最大的回文子串的长度。

由于我们用来next数组的字符串是str+reverse拼接的,最终有可能最大匹配前缀和后缀的长度超过了str的长度,所以最终求得的next[strlen(str+rever)]如果大于str的长度,就需要减去str的长度。当然也可以在拼接的时候在str和reverse中间插入一个特殊字符(str中不会出现的字符),即str+‘#’+reverse,来避免最大匹配前缀和后缀的长度超过str的长度。

string shortestPalindrome(string s) {
//生成新string
string reverse_s = s;
reverse(reverse_s.begin(), reverse_s.end());
string str = s + '#' + reverse_s;
//求next数组
vector<int> next(str.size() + 1);
next[0] = -1;
int k = -1;
int j = 0;
while (j < next.size()) {
while (k >= 0 && str[k] != str[j]) k = next[k];
++j;
++k;
next[j] = k;
}
//需要逆序插到前面的子串
string pre = s.substr(next[str.size()], s.size() - next[str.size()]);
reverse(pre.begin(), pre.end());
return pre + s;
}

LeetCode 214 Shortest Palindrome的更多相关文章

  1. [LeetCode] 214. Shortest Palindrome 最短回文串

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

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

  3. 【LeetCode】214. Shortest Palindrome 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 前缀是否回文 判断前缀 相似题目 参考资料 日期 题 ...

  4. 【LeetCode】214. Shortest Palindrome

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

  5. 214. Shortest Palindrome

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

  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

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

  8. 214 Shortest Palindrome 最短回文串

    给一个字符串 S, 你可以通过在字符串前面添加字符将其转换为回文串.找到并返回可以用这种方式转换的最短回文串.例如:给出 "aacecaaa",返回 "aaacecaaa ...

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

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

随机推荐

  1. JavaScript的学习3

    一.数组 1.定义数组格式:var 变量名 = [数组元素1,数组元素2] 2.遍历数组元素: 格式: var arr = []; for(var i=0;i<数组长度;i++){ arr[i] ...

  2. Java 对象,数组 与 JSON 字符串 相互转化

    当 Java 对象中包含 数组集合对象时,将 JSON 字符串转成此对象. public class Cart{} public class MemberCoupon{} public class C ...

  3. tomcat6配置jndi连接数据库的方式

    eworkflow工作流+eform表单+ebiao报表集成在一起,用tomcat6发布,并用jndi连接数据库,数据库是sqlserver2005,配置如下: 1.在tomcat6\conf\con ...

  4. ubuntu 13.10 mono asp.net服务 安装

    ubuntu 13.10 从官方文档http://www.mono-project.com/Mod_mono 可看到 Mod_Mono is an Apache 2.0/2.2/2.4.3 modul ...

  5. 用:before :after 来写一些小特效

    提起:before :after首先想到的是 —— 用它来去浮动来我们来换个方式玩接下来展示三种用:before :after来实现的特效 希望能起到抛砖引玉的作用 <一>第一种就是常见的 ...

  6. gdb汇编调试

    GDB调试汇编堆栈分析 代码: sudo apt-get install libc6-dev-i386命令安装所需库 进入之后先在main函数处设置一个断点,再run一下,使用disassemble指 ...

  7. lua弱表引用

    1.普通垃圾回收 --lua弱表,主要是删除key或者value是table的一种元方法 --元表里的__mode字段包含k或者v:k表示key为弱引用:v表示value为弱引用 local test ...

  8. 9、SQL Server 操作数据

    插入数据 使用Insert Into 插入 if(exists(select * from sys.databases where name = 'webDB')) drop database web ...

  9. Foundation ----->NSDictionary

    /*_______________不可变字(NSDictionary)____________*/          //1.字典的创建     //值(value)     NSArray *arr ...

  10. Redis的介绍和常用数据类型结构命令的总结

    我们先来看一下redis的一个定义,来自官方的: Redis is an open source, BSD licensed, advanced key-value store. It is ofte ...