首先讲讲什么是回文, 看看Wiki是怎么说的:回文,亦称回环,是正读反读都能读通的句子。亦有将文字排列成圆圈者,是一种修辞方式和文字游戏。回环运用得当。能够表现两种事物或现象相互依靠或排斥的关系, 比方madam,abba,这样正反都一样的串就是回文串。

今天要写的问题了就是在一个字符串中找出最长的回文字串。比方串:"abcdedabakml"。 他的最长回文字串就是"abcdedaba"。一般的方法有暴力法,动态规划法,今天来写一个时间复杂度为O(n)的算法。

回文匹配,普通情况会分奇数和偶数来分开进行设计算法来统计,今天介绍的算法又一次构造了一个字符串,这个新字符串消除了之前的奇偶区别,使得仅仅用设计一种算法就能够。

     1. 首先,构造新的字符串T

          构造方法:在原字符串S的首尾和每一个字符之间增加一个特殊字符'#', 比如S: abba, 则构造后为T: #a#b#b#a#(注:在程序中为防止越界会在首尾再加两个字符,即^#a#b#b#a#$);

     2. 关键算法:

          a[ ]: a[i]代表以位置 i 为中心向左向右可扩展的长度

          idx: 当前取得最大回文的中心位置

          R: 以 idx 为中心。向右扩展 p[idx] 位的最右位置

          j:  与 i 关于 idx 对称的位置

          

           i:   0  1 2 3 4 5 6 7 8 9

          T:  ^ # a # b # b # a # $

          a:     0 1 0 1  4 1 0 1 0

                             idx        R



          此算法的关键之处在于: 当 i<R时,a[i] 有例如以下简便计算公式 a[i] = min(R-i, a[j]):

              A. 当 R - i > a[j] 的时候,以T[j]为中心的回文子串包括在以T[mid]为中心的回文子串中,因为 i 和 j 对称,以T[i]为中心的回文子串必定包括在以T[mid]为中心的回文子串中,所以必有 a[i] = a[j], 例如以下图:此时a[i] = a[j] = 1;

             

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc3dhZ2xl/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

           B. 当 R - i < a[j] 的时候,以T[j]为中心的回文子串不一定全然包括于以T[mid]为中心的回文子串中。可是基于对称性可知,下图中两个绿框所包围的部分是同样的,也就是说以S[i]为中心的回文子串,其向右至少会扩张到 R 的位置,也就是说 a[i] >= R-i。至于R之后的部分是否对称,就仅仅能老老实实去匹配了。

          

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc3dhZ2xl/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

     3. 得到所求字符串

          找出 p[ ] 数组中最大的值及其下标,记为max和index。

          所求字符串为string(s, (index-1-max)/2, max)



     4. 实现算法:

          // Transform S into T.
// For example, S = "abba", T = "^#a#b#b#a#$".
// ^ and $ signs are sentinels appended to each end to avoid bounds checking
string preProcess(string s) {
int n = s.length();
if (n == 0) return "^$";
string ret = "^";
for (int i = 0; i < n; i++)
ret += "#" + s.substr(i, 1);
ret += "#$";
return ret;
} string longestPalindrome(string s) {
string T = preProcess(s);
int n = T.length();
int *a = new int[n];
int mid = 0, R = 0;
for (int i = 1; i < n-1; i++) {
int j = 2*mid-i; // 找到i关于mid对称的位置
a[i] = (R > i) ? min(R-i, a[j]) : 0;
// Attempt to expand palindrome centered at i
while (T[i + 1 + a[i]] == T[i - 1 - a[i]])
a[i]++;
// If palindrome centered at i expand past R,
// adjust center based on expanded palindrome.
if (i + a[i] > R) {
mid = i;
R = i + a[i];
}
}
// Find the maximum element in a.
int maxLen = 0;
int centerIndex = 0;
for (int i = 1; i < n-1; i++) {
if (a[i] > maxLen) {
maxLen = a[i];
centerIndex = i;
}
}
delete[] a;
return s.substr((centerIndex - 1 - maxLen)/2, maxLen);
}

參考文章:

http://leetcode.com/2011/11/longest-palindromic-substring-part-ii.html

假设你认为本篇对你有收获,请帮顶。

另外,我本人开通了微信公众号--分享技术之美,我会不定期的分享一些我学习的东西.
你能够搜索公众号:swalge 或者扫描下方二维码关注我


(转载文章请注明出处: http://blog.csdn.net/swagle/article/details/24384693 )

Longest Palindromic Substring-----最长回文子串的更多相关文章

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

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

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

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

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

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

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

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

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

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

  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. 【LeetCode】5. Longest Palindromic Substring 最长回文子串

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

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

    要求: Given a string S, find the longest palindromic substring in S. (从字符串 S 中最长回文子字符串.) 何为回文字符串? A pa ...

  9. 【翻译】Longest Palindromic Substring 最长回文子串

    原文地址: http://articles.leetcode.com/2011/11/longest-palindromic-substring-part-i.html 转载请注明出处:http:// ...

  10. LeetCode5. Longest Palindromic Substring 最长回文子串 4种方法

    题目链接:https://leetcode.com/problems/longest-palindromic-substring/ 题意很简单,就是求一个字符串得最长子串,这里的子串指连续的. 本文给 ...

随机推荐

  1. [bzoj1003][ZJOI2006][物流运输] (最短路+dp)

    Description 物流公司要把一批货物从码头A运到码头B.由于货物量比较大,需要n天才能运完.货物运输过程中一般要转停好几个码头.物流公司通常会设计一条固定的运输路线,以便对整个运输过程实施严格 ...

  2. SPRING源码分析:IOC容器

    在Spring中,最基本的IOC容器接口是BeanFactory - 这个接口为具体的IOC容器的实现作了最基本的功能规定 - 不管怎么着,作为IOC容器,这些接口你必须要满足应用程序的最基本要求: ...

  3. Android控件TextView的实现原理分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/8636153 在前面一个系列的文章中,我们以窗口 ...

  4. ios打包应用程序,生成ipa文件

    假设我的程序调试好了,怎么才干发给别人用呢?正常情况下IPA文件是从Xcode的Organizer中输出的,可是我们没有证书,这样输出会产生错误. 以下教你怎样生成ipa文件: 1.到你当前proje ...

  5. asp.net 页面上传文件控件后台代码Request.Files获取不到

    今天开发中遇到页面文件上传控件选择了文件,而后台Request.Files.Count取值为0,之前开发中遇到过几次,老是忘掉,今天记下来. html: <input type="fi ...

  6. BackgroundWorker 后台进程控制窗体label、richtextbook内容刷新

    昨天写了一个从文章中提取关键词的程序,写完处理的逻辑后又花了好几个小时在用户友好性上.加了几个progressBar,有显示总进度的.有显示分布进度的..因为程序要跑好几个小时才能执行好,只加个总进度 ...

  7. hdu1166 经典线段入门

    敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  8. 迁移google code上的项目到本地版本库

    今年五月份以来就已经连接不上google code了,翻*墙又极度不稳定,在忍受了几个月之后终于决定将项目搬离google code;经过研究之后终于实现了搬迁到本地,最后总结成下文.一者期望对有需要 ...

  9. 配置Tomcat中的Context元素中的中文问题

    发布一个名叫helloapp的web应用,helloapp位于D:\我\helloapp.发布的方式是通过配置<CATALINA_HOME>/conf/Catalina/localhost ...

  10. 配置chrome支持本地(file协议)ajax请求

    将html代码拖拽进入chrome通过file协议浏览时,发送的ajax请求本地文件,会报跨域错误. XMLHttpRequest cannot load file:///E:/webs/extJS/ ...