题目链接:Longest Palindromic Substring

1. 问题描述

Given a string S, find the longest palindromic substring in S. You may assume that the maximum length of S is 1000, and there exists one unique longest palindromic substring.

2. 各种解法复杂度

  • 暴力枚举:O(N^2)
  • 记忆化搜索:O(N^2)
  • 动态规划:O(N^2)
  • Manacher’s Algorithm : O(N)

3. Manacher’s Algorithm

步骤:

  1. 字符串里相邻两个字符之间插入一个 # ,开头和结尾也加上 # 。

    例如:

    Str = “abaaba”, Trans = “#a#b#a#a#b#a#”.

    注:Trans 为 transform

  2. 声明一个数组 P[n] : 其中 n 为 Trans 的长度。P[index] 表示以 index 为中心的最长回文串长度(不包括 index 本身)。例如:

    Trans = # a # b # a # a # b # a #
    P = 0 1 0 3 0 1 6 1 0 3 0 1 0

    声明变量 Cur :表示当前回文串最长的中心的下标(current position),初值为0。

    声明变量 Right : 表示以Cur为中心的回文串最右一个字符所处位置。

  3. 建立循环,以增量 index 为中心,扩展 index 。也就是检查 index 两边是否相等。如果相等, P[index] 加1。

    在循环体中:

    • 变量 index :

      当前检查的元素的下标。
    • 声明变量 index_ mirror

      以Cur为对称轴, index 的对称位置,index_mirror = Cur - ( index - Cur )
    • 在扩展之前检查 Right 是否大于 index :

      如果是,那么 P[index] 的值直接赋值为 min(R - index, P[index_mirror]) ;否则P[index] = 0。
  4. 如果 index + P[index] > Right ,将 Cur 更新为 index 。

  5. 找出 P[] 的最大值即是答案。

4. Q&A

  • 为什么要插入 # ?

    比如 abba ,以第一个 b 的下标为 index ,如果要比较 index 的回文,那么它就得比较 index 和 index+1

    如果插入 #a#b#b#a# ,第一个 b 后面的 # 下标为 index ,则比较 index - 1 和 index + 1 这样代码更清晰,也更好理解。此时 # 的 P[] 值就表示该位置的回文串长度。

  • 其他



    如上图。由于我们已经检查出 Cur 位置的回文串长度是 9 ,那么 Cur 左右两边的 9 个字符是对称的。如果 index_mirror 的 P[] 值小于等于 R-index 的值(即距离),那么令 P[index] = P[index_mirror] ——对称的性质。为什么要小于他们的距离?因为如果大于他们的距离,例如图中最左边的 a ,它回文串的范围超出了 Cur 回文串的范围,超出 Cur 范围的对称性是未知的。从图中我们可以看出,在对称右边的 a 显然 P[] 值跟左边的不相等,它是 1 。此时只能以 index 为中心继续比较(而不是直接令 P[index] = P[index_mirror] ,因为对称性质无法使用)。

    在检测 index 的最大回文串时,如果检测到 index 的回文串长度最右侧大于 Cur 的最右侧,也就是 Right ,那么将 Cur 更新为 index 。因为如果后面的元素本来可以用更新前 Cur 的对称性,那么更新后的 Cur 的对称性它同样可以用。而 Cur 的更新会使得更后面的元素可以用其对称性。

参考链接:

  1. Longest Palindromic Substring Part II
  2. Manacher's ALGORITHM: O(n)时间求字符串的最长回文子串
  3. soulmachine/leetcode -- Github

字符串的最长回文串:Manacher’s Algorithm的更多相关文章

  1. leetcode.字符串.409最长回文串-Java

    1. 具体题目 给定一个包含大写字母和小写字母的字符串,找到通过这些字母构造成的最长的回文串.在构造过程中,请注意区分大小写.比如 "Aa" 不能当做一个回文字符串. 注意: 假设 ...

  2. Palindrome(最长回文串manacher算法)O(n)

     Palindrome Time Limit:15000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit ...

  3. Manacher模板(O(n)内求最长回文串长度)

    转自:https://segmentfault.com/a/1190000008484167 /* 由于回文分为偶回文(比如 bccb)和奇回文(比如 bcacb),而在处理奇偶问题上会比较繁琐,所以 ...

  4. POJ 3974 回文串-Manacher

    题目链接:http://poj.org/problem?id=3974 题意:求出给定字符串的最长回文串长度. 思路:裸的Manacher模板题. #include<iostream> # ...

  5. 算法笔记_032:最长回文串(Java)

    目录 1 问题描述 2 解决方案 2.1 中心扩展法 2.2 Manacher算法   1 问题描述 给定一个字符串,求它的最长回文子串的长度. 2 解决方案 2.1 中心扩展法 此处,首先枚举出回文 ...

  6. Java实现最长回文串

    1 问题描述 给定一个字符串,求它的最长回文子串的长度. 2 解决方案 2.1 中心扩展法 此处,首先枚举出回文串的中心位置,然后,再在该位置上分别向左和向右扩展,记录并更新得到的最长回文串的长度. ...

  7. Manacher算法 - 求最长回文串的利器

    求最长回文串的利器 - Manacher算法 Manacher主要是用来求某个字符串的最长回文子串. 不要被manacher这个名字吓倒了,其实manacher算法很简单,也很容易理解,程序短,时间复 ...

  8. 计算字符串的最长回文子串 :Manacher算法介绍

    转自: http://www.open-open.com/lib/view/open1419150233417.html Manacher算法 在介绍算法之前,首先介绍一下什么是回文串,所谓回文串,简 ...

  9. BZOJ.2565.[国家集训队]最长双回文串(Manacher/回文树)

    BZOJ 洛谷 求给定串的最长双回文串. \(n\leq10^5\). Manacher: 记\(R_i\)表示以\(i\)位置为结尾的最长回文串长度,\(L_i\)表示以\(i\)开头的最长回文串长 ...

随机推荐

  1. Hey,man,are you ok? -- 关于心跳、故障监测、lease机制

    电话之于短信.微信的一个很大的不同点在于,前者更加及时,有更快速直接的反馈:而后面两个虽然称之为instant message,但经常时发出去了就得等对方回复,等多久是不确定的.打电话能明确知道对方在 ...

  2. HttpClient 上传多个文件

    using (System.Net.Http.HttpClient client = new System.Net.Http.HttpClient()) { client.BaseAddress = ...

  3. Mego开发文档 - 数据库建模

    数据库建模 我们还提供了一些其他的特性,用于定制化数据库对应的数据结构. 表映射 框架默认会使用CLR类型名称做为实际数据库的表名,当两者不一致时可以使用该特性强制表名称. [Table(" ...

  4. GIT入门笔记(17)- 创建分支dev_lsq, 提交到代码

    git服务器上默认的已经有主干和test分支. 开发人员提交代码流程如下: 1.用switch to->new branch创建dev1分支 2.push branch提交到dev1分支 3.在 ...

  5. Python3安装Requests

    安装Requests费了1天的时间,囧.终于还是在官网找到解决方法,可以参考这个http://docs.python-requests.org/en/latest/user/install/#inst ...

  6. Map 接口简明

    Map 接口并没有继承Collection接口 HashMap : 哈希表数据结构,是线程不同步的,快速.允许存储 null 键,null 值.替代了 Hashtable. LinkedHashMap ...

  7. MyBatis基础学习笔记--摘录

    1.MyBatis是什么? MyBatis源自于IBatis,是一个持久层框架,封装了jdbc操作数据库的过程,使得开发者只用关心sql语句,无需关心驱动加载.连接,创建statement,手动设置参 ...

  8. java中匿名内部类的应用

    如果某一个类实现了接口,而且仅仅在程序代码中使用了一次,那么就没必要单独定义该方法,可以通过接口来定义匿名内部类 interface Message{ public void print(); } p ...

  9. [LeetCode] Number of Longest Increasing Subsequence 最长递增序列的个数

    Given an unsorted array of integers, find the number of longest increasing subsequence. Example 1: I ...

  10. [LeetCode] Shortest Unsorted Continuous Subarray 最短无序连续子数组

    Given an integer array, you need to find one continuous subarray that if you only sort this subarray ...