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

思路:

写了三份代码,各种超时。知道肯定要用之前学了几遍也记不住的方法了--判断最长回文的O(N)算法Manacher算法。

特别注意:

s[i]这样的写法非常耗时!

    //Manacher算法
string shortestPalindrome(string s){
if(s.size() <= ) return s;
string ss = "$#";
for(auto c : s) //这样写只需要12ms
ss+=c, ss+='#';
//for(int i = 0; i < s.size(); ++i) //先把字符串转换一下 这样写非常慢 240ms时间都耗在这里了
// ss = ss + s[i] + "#"; vector<int> P( * s.size() + , ); //存储以i为中心回文的最大半径
int e = ;
int id = , mx = ; //id为可以管的最远的回文的中心点 mx是id可以管到的最远距离 在回文的后面一个位置
for(int i = ; i < ss.size(); ++i)
{
P[i] = (mx > i) ? min(P[ * id - i], mx - i) : ; //根据之前的信息 获取当前中心点的最短回文长度
while(i + P[i] < ss.size() && ss[i + P[i]] == ss[i - P[i]]) //扩展回文长度 注意不要越界
P[i]++;
if(i + P[i] > mx) //更新最远距离和中心点
{
mx = i + P[i];
id = i;
}
if(i == P[i]) e = i + P[i] - ; //该回文的第一个位置是源字符串的第一个字母 记录回文截至位置
}
e = e / - ; //把回文最长的截至位置转换为在原字符串中的位置
string rs = s.substr(e + , s.size() - e); //在字符串前面补上不够回文的部分
reverse(rs.begin(), rs.end());
return rs + s;
}

大神4ms的代码,其实思路都一样,可大神的代码时间就是短!

string shortestPalindrome(string s) {
int n1=s.length();
string mystr="$";//2*n1+1
int n=*n1+;
for(auto c : s)
mystr+=c, mystr+='$';
int* plen=new int[n];
int pali_len=;
int i, k, mid=, l=-;
for(i=; i<=n/; i++)
{
k=;
if(i<l&&*mid-i>-) k=min(plen[*mid-i], l-i);
while(i-k->-&&i+k+<n&&mystr[i-k-]==mystr[i+k+]) k++;
plen[i]=k;
if(i+k>l) mid=i, l=i+k;
}
for(i=n/; i>-; i--)
if(plen[i]==i) {pali_len=i; break;}
string t=s.substr(i);
reverse(t.begin(), t.end());
return t+s;
}

三个超时的常规思路代码:

bool isPalindrome(string s, int start, int end)
{
while(start <= end)
if(s[start++] != s[end--])
return false;
return true;
} //超时
string shortestPalindrome1(string s) {
if(s.size() <= ) return s;
int e = ;
for(int i = s.size() - ; i >= ; --i) //找到包括第一个字母的最长回文
{
if(isPalindrome(s, , i))
{
e = i;
break;
}
} string rs = s.substr(e + , s.size() - e);
reverse(rs.begin(), rs.end());
return rs + s;
} //超时
string shortestPalindrome2(string s){
if(s.size() <= ) return s;
for(int i = s.size() - ; i >= ; --i) //遍历可能回文的最后一个位置
{
if(s[i] == s[]) //如果第一个字符和最后位置相同
{
int slen = (i + ) / ; //回文一半的长度 奇数个则不要最中间的
string s1 = s.substr(, slen);
string s2 = s.substr(i - slen + , slen);
reverse(s2.begin(), s2.end());
if(s1 == s2) //是回文
{
string rs = s.substr(i + , s.size() - i);
reverse(rs.begin(), rs.end());
return rs + s;
}
}
}
} //超时
string shortestPalindrome3(string s){
if(s.size() <= ) return s;
for(int i = s.size() - ; i >= ; --i) //遍历可能回文的最后一个位置
{
if(s[i] == s[]) //如果第一个字符和最后位置相同
{
int slen = (i + ) / ; //回文一半的长度 奇数个则不要最中间的
string s1 = s.substr(, slen);
string s2 = s.substr(i - slen + , slen);
reverse(s2.begin(), s2.end());
unordered_set<string> uset;
uset.insert(s1);
if(uset.find(s2) != uset.end())
{
string rs = s.substr(i + , s.size() - i);
reverse(rs.begin(), rs.end());
return rs + s;
}
}
}
}

【leetcode】Shortest Palindrome(hard)★的更多相关文章

  1. 【Leetcode】Shortest Palindrome

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

  2. 【leetcode】1278. Palindrome Partitioning III

    题目如下: You are given a string s containing lowercase letters and an integer k. You need to : First, c ...

  3. 【LeetCode】336. Palindrome Pairs 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 HashTable 相似题目 参考资料 日期 题目地 ...

  4. 【LeetCode】9. Palindrome Number 回文数

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 公众号:负雪明烛 本文关键词:回文数,回文,题解,Leetcode, 力扣,Python ...

  5. 【LeetCode】234. Palindrome Linked List 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 题目地址:https://leetcode.c ...

  6. 【LeetCode】131. Palindrome Partitioning 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 回溯法 日期 题目地址:https://leetco ...

  7. 【leetcode】Valid Palindrome

    题目简述: Given a string, determine if it is a palindrome, considering only alphanumeric characters and ...

  8. 【题解】【字符串】【Leetcode】Valid Palindrome

    Given a string, determine if it is a palindrome, considering only alphanumeric characters and ignori ...

  9. 【leetcode】9. Palindrome Number

    题目描述: Determine whether an integer is a palindrome. Do this without extra space. 解题分析: ^_^个人觉得这道题没有什 ...

随机推荐

  1. 大熊君大话NodeJS之------Stream模块

    一,开篇分析 流是一个抽象接口,被 Node 中的很多对象所实现.比如对一个 HTTP 服务器的请求是一个流,stdout 也是一个流.流是可读,可写或兼具两者的. 最早接触Stream是从早期的un ...

  2. Linux运维初级教程(二)账户与安全

    知识点 用户ID为UID,组ID为GID,UID=0表示超级管理员即root. 一个用户只可以加入一个基本组,但是可以同时加入多个附加组. 创建用户时,系统默认会自动创建同名的组,并设置用户加入该基本 ...

  3. 字符编码-UNICODE,GBK,UTF-8区别【转转】

    字符编码介绍及不同编码区别 今天看到这篇关于字符编码的文章,抑制不住喜悦(总结的好详细)所以转到这里来.转自:祥龙之子http://www.cnblogs.com/cy163/archive/2007 ...

  4. 装X之写博客

    博客作用: 为了温习以前的知识,记录下 前几天和一个前辈聊天,说起看书总是前面学後面忘点的事情· 写个博客试试?

  5. OC第三节——NSArray和NSMutableArray

    1.OC数组和c数组的区别        C语言的数组:            相同类型变量的有序结合. 类型:可以是简答数据类型.构造数据类型                int     a[10 ...

  6. 小明系列问题――小明序列(LIS)

    小明系列问题――小明序列 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit ...

  7. 【C语言入门教程】2.6 运算符

    运算符是程序中用于数值运算的操作符,C 语言的运算符可分为 算术运算符.关系与逻辑运算符 和 位操作运算符 这 3 类. 2.6.1 算术运算符 算术运算符用来完成基本的数值运算,如 加.减.乘.除, ...

  8. mysql-mysql悲观锁和乐观锁

    1.mysql的四种事务隔离级别 I. 对于同时运行多个事务,当这些事务访问数据库中的相同数据时,如果没有采取必要的隔离机制,就会导致各种并发问题. (1)脏读: 对于两个事物 T1, T2, T1 ...

  9. jQuery的常用函数扩展

    (function ($) { /**************************获得URL的参数************************************/ //参数:URL中的参 ...

  10. 专业版Unity技巧分享:使用定制资源配置文件

    http://unity3d.9tech.cn/news/2014/0116/39639.html 通常,在游戏的开发过程中,最终会建立起一些组件,通过某种形式的配置文件接收一些数据.这些可能是程序级 ...