题目链接:https://leetcode.com/problems/longest-palindromic-substring/

题意很简单,就是求一个字符串得最长子串,这里的子串指连续的。

本文给出四个不同时间的解法。在LeetCode上的用时分别是500ms,250ms,60ms以及6ms。

(1)500ms-最朴素解法

这种解法相当于模拟求解了,是一种正向思维,即枚举所有起点和终点,判断长度是否最长,且是回文的。时间复杂度O(n3).代码如下:

 class Solution {
public:
string longestPalindrome(string s) {
int maxlen = ;
int len = s.length();
string ans;
int r = ,l = ; for(int i = ; i < len; i++)
{
for(int j = len - ; j > i; j--)
{
if (j - i + <= maxlen) break;
bool flag = ;
for(int k = ; k < (j - i + ) / ; k++)
{
if(s[i + k] != s[j - k])
{
flag = ;
break;
}
}
if(flag == )
{
maxlen = j - i + ;
l = i;
r = j;
}
}
}
return s.substr(l,r - l + );
}
};

(2)250ms----DP

以空间换时间,定义一个布尔类型的数组p[][],负责存储以 i、j 为左右界的子串是否为回文的。然后再遍历一遍,寻找是回文且最长的。时间复杂度O(n2)。

在求解 p 数组时,采用的策略是不断扩大 p 的长度,易知:

p[i][i] = true;

p[i][i+1] = (s[i] ==  s[i+1]);

那么,当长度为 k+1 时,有

p[i][i+k] = (p[i + 1][i + k - 1]) && (s[i] == s[i+k]);

从上式可以看出,要求长度为 k+1 时的回文与否,就得知道长度为 k 时的回文与否。因而代码如下:

 class Solution {
public:
string longestPalindrome(string s) {
int maxlen = ;
int len = s.length();
int r = ,l = ;
bool p[][];
for(int i = ; i < len; i ++)
{
p[i][i] = true;
p[i][i+] = s[i] == s[i+];
}
for(int k = ; k < len; k++)
{
for(int i = ; i < len && i + k < len; i++)
{
p[i][i+k] = s[i] == s[i+k] && p[i+][i+k-];
}
}
for(int i = ; i < len; i++)
for(int j = ; j < len; j ++)
if(p[i][j] && j - i + > maxlen)
{
l = i;
r = j;
maxlen = j - i + ;
} return s.substr(l,r - l + );
}
};

(3)60ms---中心扩展法

前面两种都是正向思维,后面这两种是以解为起点,逆向构造回文子串。解法(3)最坏时间复杂度是O(n2),虽然时间复杂度与解法(2)是一样的,但是逆向求解很大程度上减少了遍历的次数,达不到回文的基本条件就不会继续扩展,在很大程度上降低了时间代价。

这种解法也可叫做从中间扩散(ExpandAroundCenter)。奇数子串:以 i 为中心,向外扩展;偶数子串:以 (i,i+1)为中心,向外扩展。扩展时满足:左右界不超出字符串边界且对称相等。以上述方法算出以 i 为中心的奇/偶数子串中长的一个作为当前的回文子串长度temp,然后比较temp与maxlen,重复该步骤求出最终解。

其中,确定了temp后,如何获得该子串的左右界需要考虑一下,举个实例就算出来了:l = i - (temp - 1) / 2, r = temp - 1 + l; 其实 l 算出来了,根据 temp = r - l + 1 就可以求出 r 了。

代码如下:

 class Solution {
public:
string longestPalindrome(string s) {
int maxlen = ;
int len = s.length();
int r = ,l = ;
for(int i = ; i < len; i ++)
{
int temp = max(expandAroundCenter(s,i,i),expandAroundCenter(s,i,i+));
if(temp > maxlen)
{
l = i - (temp - ) / ;
r = temp - + l;
maxlen = temp;
}
}
return s.substr(l,r - l + );
}
private:
int expandAroundCenter(string s, int l, int r)
{
while(l >= && r < s.length() && s[l] == s[r])
{
l--;
r++;
}
return r - l - ;
}
};

(4)6ms---改进的中心扩展法

由解法(1)到解法(3)的过程中可以看出,缩短时间的思想是不断减少不必要的计算或重复的计算。解法(4)就是在解法(3)的基础上进一步缩减重复的计算。缩减的策略是,不是以一个字符 i 为中心计算其奇数或偶数长度的回文子串,而是以一个由相同字符组成的连续子串为中心向外扩展。仔细想想其实是很有道理的。字符个数总共只有128个,当字符串长度很大时,构成回文子串的字符中最有可能是重复的字符反复出现。从最终的运行时间可能看出这种策略的优势,比解法(3)平均缩短了10倍的时间。

代码如下:

 class Solution {
public:
std::string longestPalindrome(std::string s) {
if (s.size() < )
return s;
int len = s.size(), max_left = , max_len = , left, right;
for (int start = ; start < len && len - start > max_len / ;) {
left = right = start;
while (right < len - && s[right + ] == s[right])//求出重复字符组成的子串的右界
++right;
start = right + ;//下一轮遍历的起点。
while (right < len - && left > && s[right + ] == s[left - ]) {//不断向外扩展
++right;
--left;
}
if (max_len < right - left + ) {
max_left = left;
max_len = right - left + ;
}
}
return s.substr(max_left, max_len);
}
};

总结:主动寻找构造解的方式 比 被动搜索解的方式 效率更高!

LeetCode5. Longest Palindromic Substring 最长回文子串 4种方法的更多相关文章

  1. Longest Palindromic Substring (最长回文字符串)——两种方法还没看,仍需认真看看

    Given a string S, find the longest palindromic substring in S. You may assume that the maximum lengt ...

  2. Leetcode 5. Longest Palindromic Substring(最长回文子串, Manacher算法)

    Leetcode 5. Longest Palindromic Substring(最长回文子串, Manacher算法) Given a string s, find the longest pal ...

  3. LeetCode-5:Longest Palindromic Substring(最长回文子字符串)

    描述:给一个字符串s,查找它的最长的回文子串.s的长度不超过1000. Input: "babad" Output: "bab" Note: "aba ...

  4. LeetCode:Longest Palindromic Substring 最长回文子串

    题目链接 Given a string S, find the longest palindromic substring in S. You may assume that the maximum ...

  5. lintcode :Longest Palindromic Substring 最长回文子串

    题目 最长回文子串 给出一个字符串(假设长度最长为1000),求出它的最长回文子串,你可以假定只有一个满足条件的最长回文串. 样例 给出字符串 "abcdzdcab",它的最长回文 ...

  6. [leetcode]5. Longest Palindromic Substring最长回文子串

    Given a string s, find the longest palindromic substring in s. You may assume that the maximum lengt ...

  7. 5. Longest Palindromic Substring(最长回文子串 manacher 算法/ DP动态规划)

    Given a string s, find the longest palindromic substring in s. You may assume that the maximum lengt ...

  8. [LeetCode] 5. Longest Palindromic Substring 最长回文子串

    Given a string s, find the longest palindromic substring in s. You may assume that the maximum lengt ...

  9. 【LeetCode】5. Longest Palindromic Substring 最长回文子串

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 公众号:负雪明烛 本文关键词:最长回文子串,题解,leetcode, 力扣,python ...

随机推荐

  1. 无图无定位新版css步骤条兼容ie6+

    <ul class="ui-step list-unstyled"> <li class="step-item"><b class ...

  2. 在ExpressJS中设置二级域名跨域共享Cookie

    问题:我使用expressjs和mongostore来管理session.下面是expressjs中的设置. app.configure(function(){ app.use(express.ses ...

  3. String 类的实现(1)浅拷贝存在的问题

    浅拷贝 : 也称位拷贝 , 编译器只是直接将指针的值拷贝过来, 结果多个对象共用 同 一块内 存, 当一个对象将这块内 存释放掉之后, 另 一些对象不知道该块空间 已经还给了 系 统, 以 为还有效, ...

  4. selenium自动化过程中如何操作Flash动画

    最近在看python的爬虫框架(scrapy),一个词概括就是:"酸爽"!等把selenium自动化版块讲完后,打算写一写关于scrapy相关的知识,打算从源码角度解析下scrap ...

  5. 使用HTML5的canvas做图片剪裁

    前言 图片裁剪上传,不仅是一个很贴合用户体验的功能,还能够统一特定图片尺寸,优化网站排版,一箭双雕. 需求就是那么简单,在浏览器里裁剪图片并上传到服务器. 我第一个想到的方法就是,将图片和裁剪参数(x ...

  6. 解决Mybatis连接Sql server 出现 Cannot load JDBC driver class 'com.mysql.jdbc.Driver '的问题

    tomcat启动的时候没有错误,但是进行数据库操作就会有错误. 在网上找了很久  好不容易找到解决方法 转自 http://blog.csdn.net/ro_bot/article/details/5 ...

  7. 体验VS2017的Live Unit Testing

    相对于传统的Unit Test,VS2017 带来了一个新的功能,叫Live Unit Testing,从字面意思理解就是实时单元测试,在实际的使用中,这个功能就是可以在编写代码的时候进行实时的bac ...

  8. GET 请求复制转发一直等待响应的问题 Transfer-Encoding: chunked

    今天在做Proxy 转发请求的时候发现 GET的请求转发时一直在等待输出. 而Post等其它操作是可以的. 同事告诉我一般一直等待响应可能是输出内容长度和头部ContentLength不一致导致的, ...

  9. CGLIB和JDK代理

    需要的架包:在spring中提供对CGLIB的支持 一.JDK的动态代理 1.接口IUserDao package cn.itcast.spring3.jdk.proxy; public interf ...

  10. 日志框架SLF4J

    1.什么是SLF4J SLF4J:Simple Logging Facade for Java,为java提供的简单日志Facade.Facade门面,更底层一点说就是接口.它允许用户以自己的喜好,在 ...