题目

leetcode:5. Longest Palindromic Substring

解法

动态规划

时间复杂度\(O(n^2)\),空间复杂度\(O(n^2)\)

基本解法直接看代码

class Solution {
public:
string longestPalindrome(string s) {
int n = s.size();
vector<vector<bool>> dp(n, vector<bool>(n, true));
int rx, ry; rx = ry = 0;
for(int l = 1; l < n; l++){
for(int i = 0; i < n - l; i++){
int j = i + l;
if(s[i] == s[j] && (j - i < 3 || dp[i+1][j-1])){
dp[i][j] = true;
if(j - i > ry - rx){
ry = j;
rx = i;
}
} else {
dp[i][j] = false;
}
}
} return s.substr(rx, ry - rx + 1);
}
};

中心扩散法

时间复杂度\(O(n^2)\),空间复杂度\(O(1)\)

我们先假定以某点为中心向两端扩散,找到以该点为中心的最长回文子串

class Solution {
public: int rx, ry;
void helper(string &s, int i, int offset){
int left = i;
int right = i + offset;
while(left >= 0 && right < s.size() && s[left] == s[right]){
left--;
right++;
} if(right - 1 - (left + 1) > ry - rx){
ry = right - 1;
rx = left + 1;
}
}
string longestPalindrome(string s) {
int n = s.size(); rx = ry = 0; for(int i = 0; i < n; i++){
helper(s, i, 0);
helper(s, i, 1);
} return s.substr(rx, ry - rx + 1);
}
};

Manacher算法

Manacher算法俗称“马拉车算法”,时间复杂度\(O(n)\),空间复杂度\(O(n)\)

因为回文字符串都有奇数长度的串和偶数长度的串,为了更好处理这两种情况,可以在字符串中插入一特殊字符'#',使得新字符串长度全变为奇数长度,如"aa"变为"#a#a#",可以再字符串首部加入另一特殊字符'$'和尾部的'@',这样就不用特殊处理越界问题(统一边界处理)

以"122112321"为例经过上一步变成"@#1#2#2#1#1#2#3#2#1#"

Manacher算法使用一个辅助数组r[i]表示以t[i]为中心的最长回文子串的最右字符到t[i]的长度,如以t[i]为中心的最长回文子串为t[low, high],则r[i] = high - i + 1, t[low, high] = 2 * r[i]-1, len数组有一个性质,就是r[i]-1为该回文子串在原串中的长度,证明很简单t[lowl, high]一定是以"#"开头和结尾的,这样插入的"#"是原来串中字符的两倍还多一个,这样原串中最长回文串的长度就为r[i]-1,这样问题就转为求最长的r[i]

计算len数组

算法主要利用了已有的回文子串的特点,减少了查找时间,从左往右计算len[i],同时保存一个之前计算最长回文子串的右端点的最大值R及对应的中心位置c,

  • i < R, 则先找i关于c对称点j=2*c-i,则至少r[i] \(\geq\) min(R - i + 1, p[j]), 超出部分再手工匹配
  • i >= R, 则不能利用以后的知识做任何假设,只能假定其至少为1,再手工匹配
class Solution {
public: string longestPalindrome(string s) {
int n = s.size();
if(n == 0) return "";
string ns;
ns.push_back('$');
for(int i = 0; i < n; i++){
ns.push_back('#');
ns.push_back(s[i]);
}
ns.push_back('#');
ns.push_back('@');
n = ns.size();
vector<int> r(n);
int c, R, C, MAX;
R = -1;
MAX = 0;
C = 0;
for(int i = 1; i < n; i++){
r[i] = i < R ? min(r[2 * c - i], R - i + 1) : 1;
while(ns[i + r[i]] == ns[i - r[i]]) r[i]++;
r[i]--;
if(i + r[i] > R){
R = i + r[i];
c = i;
}
if(r[i] > MAX){
MAX = r[i];
C = i;
} } return s.substr((C-MAX)/2, r[C]);
}
};
时间复杂度分析

参考

最长回文子串(动规,中心扩散法,Manacher算法)的更多相关文章

  1. 【转】最长回文子串的O(n)的Manacher算法

    Manacher算法 首先:大家都知道什么叫回文串吧,这个算法要解决的就是一个字符串中最长的回文子串有多长.这个算法可以在O(n)的时间复杂度内既线性时间复杂度的情况下,求出以每个字符为中心的最长回文 ...

  2. Leetcode(5)-最长回文子串(包含动态规划以及Manacher算法)

    给定一个字符串 s,找到 s 中最长的回文子串.你可以假设 s 的最大长度为1000. 示例 1: 输入: "babad" 输出: "bab" 注意: &quo ...

  3. [LeetCode] 5. 最长回文子串 ☆☆☆(最长子串、动态规划)

    最长回文子串 (动态规划法.中心扩展算法) https://leetcode-cn.com/problems/longest-palindromic-substring/solution/xiang- ...

  4. 【LeetCode】最长回文子串【动态规划或中心扩展】

    给定一个字符串 s,找到 s 中最长的回文子串.你可以假设 s 的最大长度为 1000. 示例 1: 输入: "babad"输出: "bab"注意: " ...

  5. 【LeetCode】最长回文子串-中心扩展法

    [问题]给定一个字符串 s,找到 s 中最长的回文子串.你可以假设 s 的最大长度为 1000. 示例 : 输入: "babad" 输出: "bab" 注意: ...

  6. 51nod 1088 最长回文子串 【中心拓展法/输出长度和路径】

    1088 最长回文子串 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 收藏 关注 回文串是指aba.abba.cccbccc.aaaa这种左右对称的字符串. 输入一个字 ...

  7. 最长回文子串-LeetCode 5 Longest Palindromic Substring

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

  8. 最长回文子串(Longest Palindromic Substring)

    这算是一道经典的题目了,最长回文子串问题是在一个字符串中求得满足回文子串条件的最长的那一个.常见的解题方法有三种: (1)暴力枚举法,以每个元素为中心同时向左和向右出发,复杂度O(n^2): (2)动 ...

  9. lintcode最长回文子串(Manacher算法)

    题目来自lintcode, 链接:http://www.lintcode.com/zh-cn/problem/longest-palindromic-substring/ 最长回文子串 给出一个字符串 ...

随机推荐

  1. BOM Summary P268-P269

    The Browser Object Model(BOM) is based on the window object, which represents the browser window and ...

  2. Python:Base3(函数,切片,迭代,列表生成式)

    1.Python之调用函数: Python内置了很多有用的函数,我们可以直接调用. 要调用一个函数,需要知道函数的名称和参数,比如求绝对值的函数 abs,它接收一个参数. 可以直接从Python的官方 ...

  3. PropertyValuesProvider在日期绑定和校验中的应用

    Github地址:https://github.com/andyslin/spring-ext 编译.运行环境:JDK 8 + Maven 3 + IDEA + Lombok spring-boot: ...

  4. Django学习笔记(一)Django基础

    新建项目 django-admin startproject my_site #会在当前目录新建my_site目录,可自行修改目录名 django-admin startproject my_site ...

  5. 如何将其它javaweb项目变成可以成功在自己eclipse环境中运行的javaweb项目?

    说明:此文档仅适用于以下两种情况     (1)myeclipse项目需要在eclipse环境中运行     (2)eclipse项目,但是无法在自己的电脑eclipse环境中运行     注意:以下 ...

  6. C学习笔记-枚举

    枚举定义 可以使用枚举(enumerated type)声明代表整数常量的符号名称,关键字enum创建一个新的枚举类型 实际上,enum常量是int类型的 枚举的本质就是int型的常量 enum sp ...

  7. Tensor Flow基础(2.0)

    写在前面:此篇纯属自我记录,参考意义不大. 数据类型 数值型 标量Scalar:1.0,2.3等,shape为0->[] a = 1.2 向量Vector:[1.0],[2.3,5.4]等,sh ...

  8. Spring MVC (二)注解式开发使用详解

    MVC注解式开发即处理器基于注解的类开发, 对于每一个定义的处理器, 无需在xml中注册. 只需在代码中通过对类与方法的注解, 即可完成注册. 定义处理器 @Controller: 当前类为处理器 @ ...

  9. DiskSim

    1.使用笔记 http://feifei432.blog.163.com/blog/static/140253361201022211949152/ http://feifei432.blog.163 ...

  10. 用ufile和S3代替hdfs存储数据

    一,添加ufile需在配置中添加: core-site.xml添加如下配置:<property><name>fs.ufile.impl</name><valu ...