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. Laravel学习笔记(四)数据库 数据库迁移案例

    创建迁移 首先,让我们创建一个MySql数据库“Laravel_db”.接下来打开app/config目录下的database.php文件.请确保default键值是mysql: return arr ...

  2. 在VS中添加lib的简单方法

    1.工程---属性---配置属性---VC++ Directories---General---Include Directories:加上头文件存放目录 2.VC中,切换到"解决方案视图& ...

  3. mysql通过sql文件导入数据时出现乱码的解决办法

    首先在新建数据库时一定要注意生成原数据库相同的编码形式,如果已经生成可以用phpmyadmin等工具再整理一次,防止数据库编码和表的编码不统一造成乱码. 方法一: 通过增加参数 –default-ch ...

  4. IRC常用命令

    From: http://www.blogjava.net/ivanwan/archive/2006/02/17/31296.html IRC命令可以实现一些特殊的功能.目前,亿言堂支持14条IRC命 ...

  5. Chrome和Firefox浏览器执行new Date() 函数传参数得到不同结果的陷阱

    某日,同事问到关于new Date() 函数传参数,在火狐浏览器和谷歌浏览器控制台运行,会得到不同的结果,刚开始觉得不可能,后来实际操作才发现此陷阱 var date = new Date('2014 ...

  6. Java class file format specfication

    Java class file format spec Link: https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html Her ...

  7. 转载:最近有两款路由器D-link , Tenda分别被爆出固件中存在后门

    最近有两款路由器分别被爆出固件中存在后门. D-link D-link是台湾公司,成立于1986年,『公司致力于高级网络.宽带.数字.语音和数据通信解决方案的设计.制造和营销,是业界的全球领导者』(官 ...

  8. MVC之路由规则 (自定义,约束,debug)

    自定义路由规则的要求,小范围写在前,大范围写在后.路由规则可以注册多条,路由规则的名称不能重复路由规则有顺序,并且按照顺序进行匹配,建议小范围写在前,大范围写在后.路由规则可以设置约束 即正则表达式路 ...

  9. 关于Python3爬虫抓取网页Unicode

    import urllib.requestresponse = urllib.request.urlopen('http://www.baidu.com')html = response.read() ...

  10. Dell_R710 centos5.4 网卡(BCM5709)中断故障解决

    环境:Dell R710   Centos 5.4 i386 现象:正常运行中无故断网,没有规律 原因:RedHat As5.X 版本中的Broadcom NetXtreme II BCM 5709 ...