求最长回文子串 - leetcode 5. Longest Palindromic Substring
写在前面:忍不住吐槽几句今天上海的天气,次奥,鞋子里都能养鱼了...裤子也全湿了,衣服也全湿了,关键是这天气还打空调,只能瑟瑟发抖祈祷不要感冒了....
前后切了一百零几道leetcode的题(solution同步在github),主要是拣难度系数定为easy的水题做...好吧,这是第一道算法题。不知哪位大神说的,所有的语言都会过时,只有数据结构和算法才是永恒。
今天要重点讲的是优雅的Manacher算法,先来看这道题Longest Palindromic Substring,题目很简单,给你一个字符串,找到最长的回文子串。啥叫回文串?就是前后看都一样的串,比如abcba,abba,因为题目给的数据量不大(1000),所以可以枚举字符串的每个位置当做回文对称点,回文对称点是我给它的一个概念,比如abcba的回文对称点就是idx=2也就是c的位置。But!并不是每个回文串都有对称点,比如abba,只有对称轴,它就没有点!怎么办?机智的coder想出了一个简单的用空间换取代码实现复杂度的方法,这也是Manacher算法的第一步:
abcba -> #a#b#c#b#a#
abba -> #a#b#b#a#
这么一来,每个回文串就都有回文对称点了(可能是字母,也可能是#)。之后我们就能枚举对称点,然后向两边扩散开去,比较字符是否一样。为了不用判断是否已经到了边界,我们最初在字符串的开头再加个字符*,只要该字符和#以及字符串里其他字符都不一致即可。这样是可以AC的,虽然复杂度达到了O(n^2)。接下去我们介绍复杂度为O(n)的Manacher算法。
我们试着以字符串babcbade举例,首先把字符串像上面一样变形:
babcbade -> *#b#a#b#c#b#a#d#e#
然后我们设置一个dp数组,dp[i]表示以变形后第i个元素为对称点的最长回文子串的半径,同样以上面的字符串举例,可以得到dp数组:
*#b#a#b#c#b#a#d#e#
112121216121212121
我们可以很容易地发现,要求的最长回文子串的长度即dp数组最大值减去1。于是如何快速地求得该数组成为关键。假设我们已经得到了dp[6]的值,dp[10]的初始值也不难确定,因为它们两个元素根据idx=8对称(#a#b#c#b#a#),所以可以不用从1开始向两边扩散了。
我们用maxn维护当前存在的回文子串能达到最右的位置+1(maxn位置不可达到),用idx维护当前能到达最右+1的回文子串的回文中心点位置,实现该dp数组求值的核心代码如下:
for (var i = 1, len = str.length; i < len; i++) {
if (maxn > i) dp[i] = Math.min(dp[2 * idx - i], maxn - i);
else dp[i] = 1;
while (str[i - dp[i]] === str[i + dp[i]]) dp[i]++;
if (dp[i] + i > maxn)
maxn = dp[i] + i, idx = i;
}
完整的AC代码:
// return the Longest Palindromic Substring of s
function Manacher(s) {
var str = '*#'
, dp = []
, maxn = 0
, idx = 0;
for (var i = 0, len = s.length; i < len; i++)
str += s[i] + '#';
for (var i = 1, len = str.length; i < len; i++) {
if (maxn > i) dp[i] = Math.min(dp[2 * idx - i], maxn - i);
else dp[i] = 1;
while (str[i - dp[i]] === str[i + dp[i]]) dp[i]++;
if (dp[i] + i > maxn)
maxn = dp[i] + i, idx = i;
}
var ans = 0
, pos;
for (var i = 1; i < len; i++) {
if (dp[i] > ans)
ans = dp[i], pos = i;
}
var f = str[pos] === '#'
, tmp = f ? '' : str[pos]
, startPos = f ? pos + 1 : pos + 2
, endPos = f ? dp[pos] - 3 + startPos : dp[pos] - 4 + startPos;
for (var i = startPos; i <= endPos; i += 2)
tmp = str[i] + tmp + str[i];
return tmp;
}
var longestPalindrome = function(s) {
var str = Manacher(s);
return str;
};
求最长回文子串 - leetcode 5. Longest Palindromic Substring的更多相关文章
- 最长回文子串-LeetCode 5 Longest Palindromic Substring
题目描述 Given a string S, find the longest palindromic substring in S. You may assume that the maximum ...
- hdu 3068 最长回文(manachar求最长回文子串)
题目连接:hdu 3068 最长回文 解题思路:通过manachar算法求最长回文子串,如果用遍历的话绝对超时. #include <stdio.h> #include <strin ...
- PAT甲题题解-1040. Longest Symmetric String (25)-求最长回文子串
博主欢迎转载,但请给出本文链接,我尊重你,你尊重我,谢谢~http://www.cnblogs.com/chenxiwenruo/p/6789177.html特别不喜欢那些随便转载别人的原创文章又不给 ...
- Manacher模板( 线性求最长回文子串 )
模板 #include<stdio.h> #include<string.h> #include<algorithm> #include<map> us ...
- 求最长回文子串:Manacher算法
主要学习自:http://articles.leetcode.com/2011/11/longest-palindromic-substring-part-ii.html 问题描述:回文字符串就是左右 ...
- 后缀数组 - 求最长回文子串 + 模板题 --- ural 1297
1297. Palindrome Time Limit: 1.0 secondMemory Limit: 16 MB The “U.S. Robots” HQ has just received a ...
- Manacher算法 O(n) 求最长回文子串
转自:http://bbs.dlut.edu.cn/bbstcon.php?board=Competition&gid=23474 其实原文说得是比较清楚的,只是英文的,我这里写一份中文的吧. ...
- Manacher算法——求最长回文子串
首先,得先了解什么是回文串.回文串就是正反读起来就是一样的,如“abcdcba”.我们要是直接采用暴力方法来查找最长回文子串,时间复杂度为O(n^3),好一点的方法是枚举每一个字符,比较较它左右距离相 ...
- manacher算法求最长回文子串
一:背景 给定一个字符串,求出其最长回文子串.例如: s="abcd",最长回文长度为 1: s="ababa",最长回文长度为 5: s="abcc ...
随机推荐
- 利用PHPMailer 来完成PHP的邮件发送 #转载自:大菜鸟在云端#
利用PHPMailer 来完成PHP的邮件发送 1.首先是下载PHPMailer http://code.google.com/a/apache-extras.org/p/phpmailer/ 2.解 ...
- 摆脱npm的网络问题: 淘宝npm镜像
在使用npm install的时候, 经常会因为网络问题, 各种安装不顺利, 一个字'烦躁'. 自从遇上淘宝npm之后,执行cnpm install之后, 怎一个'快'字了得. 闲话不多说, 直接上干 ...
- 透过byte数组简单分析Java序列化、Kryo、ProtoBuf序列化
序列化在高性能网络编程.分布式系统开发中是举足轻重的之前有用过Java序列化.ProtocolBuffer等,在这篇文章这里中简单分析序列化后的byte数组观察各种序列化的差异与性能,这里主要分析Ja ...
- 56相册视频(土豆相册视频 激动相册视频 QQ动感影集等)——下载教程
由于目前流行的相册视频或影集大多是由Flash.音乐和图片组合而成的动画,不属于完整视频,所以不能用常规的解析方法下载. 鉴于很多朋友希望可以下载自己精心制作的相册,故在本教程中,我们将以图文并茂的方 ...
- POJ 1741 Tree (树的点分治入门)
Tree Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 16172 Accepted: 5272 Descripti ...
- I am back-电商网站开发&jQuery
hi 之前有将近两周的时间没有更新,除了懒就是其他的事情耽误了.现在好了,回家了,虽然家里停水,外面又有积雪,天寒地冻的,但诸多不便,都比不过有点闲的好. 开搞每个学PHP的必经之路——电商网站的开发 ...
- Beyond IT
Know Yourself <开讲啦> 20160306 潘建伟:探索的动机
- 【转】【收藏】LINQ学习心得分享--------(二)LINQ语法详解
原地址:http://blog.csdn.net/xuemoyao/article/details/8053444 通过上一章节的学习,相信大家已经掌握了学习LINQ的前期的准备知识.在这一节里, ...
- Servlet分页技术
这是看韩顺平老师的servlet视频,自己动手写的,楼主看韩顺平老师的servlet是2006制作的,用的是sql server数据库,自己又用的是oracle数据库,所以怕有的同学遇到同样的问题,不 ...
- extra增强延迟加载
这种配置和配置为lazy=true是一样的,但它的好处在于调用size/contains等方法时,并不查询整个集合的数据,而是发送一条sql语句来处理,只有真正在使用时才全部去查询整个集合