LeetCode 214 Shortest Palindrome
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的更多相关文章
- [LeetCode] 214. 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】214. Shortest Palindrome 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 前缀是否回文 判断前缀 相似题目 参考资料 日期 题 ...
- 【LeetCode】214. Shortest Palindrome
Shortest Palindrome Given a string S, you are allowed to convert it to a palindrome by adding charac ...
- 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(hard)★
Given a string S, you are allowed to convert it to a palindrome by adding characters in front of it. ...
- 【Leetcode】Shortest Palindrome
Shortest Palindrome Given a string S, you are allowed to convert it to a palindrome by adding charac ...
- 214 Shortest Palindrome 最短回文串
给一个字符串 S, 你可以通过在字符串前面添加字符将其转换为回文串.找到并返回可以用这种方式转换的最短回文串.例如:给出 "aacecaaa",返回 "aaacecaaa ...
- [LeetCode] Shortest Palindrome 最短回文串
Given a string S, you are allowed to convert it to a palindrome by adding characters in front of it. ...
随机推荐
- 超链接实现post方式提交
思路:如果想要超链接实现post方式提交,必须借助表单.下面得两种方式,一种是借助显示的form表单,一种是借助隐式的form表单方式一:将超链接放到一个form表单中,或者超链接本身就在一个form ...
- Codeforces 28C [概率DP]
/* 大连热身D题 题意: 有n个人,m个浴室每个浴室有ai个喷头,每个人等概率得选择一个浴室. 每个浴室的人都在喷头前边排队,而且每个浴室内保证大家都尽可能均匀得在喷头后边排队. 求所有浴室中最长队 ...
- Python操作Excel之xlwt
#写入import xlwtworkbook=xlwt.Workbook()sheetn=workbook.add_sheet(u"测试数据",cell_overwrite_ok= ...
- APP开发和web开发的区别
1.web开发: 1.浏览器直接访问,协议是http,基本都是PC访问,也就是在家和办公场合,网络比较好. 2.web如果多个服务集成的话使用的是ESB来统一集成 2.APP开发 1.手机app客户端 ...
- 尚学堂Spring视频教程(一):模拟Spring
Spring简单的说就是作为控制反转的容器,看这篇文章前需要先搞懂“控制反转和依赖注入“这个设计模式 我们先来模拟Spring,实现用户添加的功能,新建WEB项目”Spring_0100_Abstra ...
- 更新程序基于IIS
闲着无聊写了个更新程序; 1.支持多种文件格式 2.支持按版本号/文件大小/文件时间进行判断更新 3.支持多级文件目录创建
- oracle 分析函数
认识分析函数 分析函数是什么? 分析函数是oracle专门用于解决复杂报表统计需求的功能强大的函数,它可以在数据中进行分组然后计算基于组的某种统计值,并且每一组的每一行都可以返回一个统计值. 分析函数 ...
- 裸奔Spring(1)
pom.xml <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w ...
- html5 定位 获得当前位置的经纬度
if (navigator.geolocation) { navigator.geolocation.getCurrentPosition(showPosition, showError, { // ...
- const关键字也许该被替换为readonly
只读的变量,其值在编译时不能被使用,因为编译器在编译时不知道其存储的内容. const修饰的只读变量 const int Max = 100: int Array[Max] ; c文件中,编译 ...