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. [C#对Oracle操作]C#操作调用Orcale存储过程有参数

    /// <summary> /// 获取ERP固定资产计提数据 /// </summary> /// <param name="strCompanyCode&q ...

  2. IIS6批量添加主机头,修改IIS数据库

    首先,找到IIS的数据库.默认是在C:\WINDOWS\system32\inetsrv 下的MetaBase.xml文件. 如果找不到,请右键右键站点->所有服务->将配置保存到一个文件 ...

  3. JQuery 在循环中设置事件,最后一个覆盖了前面所有的设置

    function setValidation() {         for (i = 0; i < alValidations.length; i++) { //alValidations是一 ...

  4. WinCE\Window Mobile程序桌面化总结

    1.系统API处理 将桌面.移动API分开处理 2.一份代码,两个工程,分别编译 添加已有文件时,使用添加链接,而不是添加附本 3.桌面窗体出现位置不规律,样式不统一问题 首先,在窗体类成员加入两个成 ...

  5. django 项目的文件说明

    参见官方教程的mysite项目 mysite--- manage.py db.sqlite3 #数据库文件 mysite--- #项目文件夹 __init__.py settings.py urls. ...

  6. linux VI search command 搜索 加入行号

    VI COMMAND:set number :set nonumber VI COMMAND/keywork   //search

  7. 谈谈Java面向对象的三大特性

    Java面向对象的三大特性就是指封装.继承.多态了. 一.封装: 概念:封装是指隐藏对象的属性和实现细节,仅对外提供公共访问方式. (举例:笔记本电脑就是一个封装体,Java语言中最小的封装体就是函数 ...

  8. VS 设置编译后的程序可以以管理员身份运行

    1.首先,创建一个文件命名为 XXX.exe.manifest, 并将以下内容复制到文件 <?xml version="1.0" encoding="UTF-8&q ...

  9. C 程序解决实际文件案例

    1,C程序参数(编写带参数 的C--argc,argv[]程序),带参数的Main程序 程序功能说明: 把命令行参数中的前一个文件名标识 的文件,复制到后一个文件名标识的文件中,如只有一个则把该文件写 ...

  10. AndroidStudio中activity实现去掉标题栏

    1.在代码中实现 this.requestWindowFeature(Window.FEATURE_NO_TITLE) 这段代码需要放在setContentView()前面 2.设置在Manifest ...