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

何为回文字符串? A palindrome is a string which reads the same in both directions. For example, “aba” is a palindome, “abc” is not.

解决方法:参考:http://leetcode.com/2011/11/longest-palindromic-substring-part-ii.html

1.暴力法(Brute force solution)

共 C(N, 2) 个子串。时间复杂度O(N3)

2.后缀树法(Suffix tree solution)

反转 S 得到 S' ,例如:S = “caba”, S’ = “abac”. 求最长公共子串。求最大公共子串方法有后缀树或动态规划方法。

可参考:http://en.wikipedia.org/wiki/Longest_common_substring

注意陷阱:例如,S = “abacdfgdcaba”, S’ = “abacdgfdcaba”. 最长公共子串是 “abacd” ,明显不是回文串。

陷阱原因:S 中有它的非回文子串的反转出现。

克服方法:对于找到的公共子串,查找它在两个母串的全部下标是否都相等。

3.动态规划法(Dynamic programming solution)

时间复杂度 O(N2), 空间复杂度  O(N2)。

定义数组:

则有,

dp[i][j] = d[i+1][j-1] && S[i] == S[j]

初始条件:

dp[i][i] = ture , i = 1,……,s.length() -1.

dp[i][i+1] =  (S[i] == S[i+1]) , i = 1,……,s.length()-2

代码:

class Solution {
public:
string longestPalindrome(string s) {
/************** 动态规划 *************/
int n = s.length();
if(n == 0) return "";
bool dp[1000][1000] = {false};
int firstIndex = 0, maxLen = 1;
for(int r = 0; r <= n - 1; ++r) {
for(int index = 0; index <= n - 1 - r; ++index) {
if(s[index] == s[index + r]){
if(r < 2){
dp[index][index + r] = true;
firstIndex = index;
maxLen = r + 1;
}else if(dp[index + 1][index + r -1] == true){
dp[index][index + r] = true;
firstIndex = index;
maxLen = r + 1;
}
}
}
}
return s.substr(firstIndex, maxLen);
}
};

 4.更简单的方法

O(N2)时间,O(1)空间

分析:回文串一定有一个中心,然后关于中心对称。长度为 N 的字符串有潜在的对称中心数目为 N + (N - 1) = 2N -1。

基于每个中心去找时间复杂度为 O(N),共查找 2N-1 次。因此总的时间复杂度为 O(N(2N - 1)) ~ O(N2).

代码:

string expandAroundCenter(string s, int left, int right){
int n = s.length();
while(left >= 0 && right <= n - 1 && s[left] == s[right]){
--left;
++right;
}
return s.substr(left + 1, right - left - 1);
} class Solution {
public:
string longestPalindrome(string s) {
/************** O(n^2)time, O(1)space complexity *************/
int n = s.length();
if(n == 0) return "";
string longest = s.substr(0,1);
for(int index = 0; index < n; ++index){
string s1 = expandAroundCenter(s, index, index);
string s2 = expandAroundCenter(s, index, index + 1);
if(s1.length() > s2.length()){
if(s1.length() > longest.length()) longest = s1;
}else if(s2.length() > longest.length()) longest = s2;
}
return longest;
}
};

5.Manacher’s Algorithm

时间复杂度 O(N),空间复杂度 O(4N)

算法思路:第一步:对于输入的长度为 N 的字符串 S,在字符间的 N+1 个位置分别插入一个特殊符号 "#",得到新的字符串 T ,长度为 2N+1。

例如:S = “abaaba”, T = “#a#b#a#a#b#a#”.

第二步:定义数组 P[2N+1]。分别以 T 中每个字符为回文串的中心,查找它的半径的值,结果存放在 P 中。(注意:数组 P 中最大数等于 S 中最大回文子串的长度)

例如:

 (则 S 的最大回文子串长度为 6)。

(注意:P 中数字关于中心对称)

接下来,主要就是对第二步的分析和优化。

以下面比较复杂的字符串为例:(可以看英文解释,也可以看我的叙述)

变量解释:L 和 R 分别为以 C 为中心的回文串的左右边界,其中 L + R = 2*C。分析两种情况:

index13  关于 C 对称点为 index(2*c-13) ,即 index9 ,因为 P[9] = 1,而且 P[9] < R-12(小于左边界) ,所以 P[13] = P[9] = 1;

……

index15  关于 C 对称点为 index(2*c-15) ,即 index7 ,因为 P[7] = 7,而且 P[7] >= R-15(大于左边界) ,所以 :

首先令P[15] = P[7] = 7,然后令 C =  15,以 index15 为中心,以 T[15-P[15]-1] 和 T[15+P[15]+1] 开始比较,向两段延伸,找新的 L 和 R.

最后得到 P[15] =  13 ,L = 2,R = 8。

……

代码:(为了方便边界,两边加了的特殊符号)

string preprocess(string s){
int n = s.length();
if(n == 0) return "";
string newS = "^#";
for(int i = 0; i < n; ++i)
newS += "#" + s.substr(i,1);
newS += "#$";
return newS;
} class Solution {
public:
string longestPalindrome(string s) {
/************** O(n)time, O(4n)space complexity *************/
string T = preprocess(s);
int n = T.length();
if(n == 0) return "";
int *p = new int[n];
int C = 0, R = 0;
int maxLen = 1, firstIndex = 0;
for(int i = 1; i < n-2; ++i){
int i_mirror = 2 * C - i;
p[i] = (R > i) ? min(R - i, p[i_mirror]) : 0;
while(T[i + p[i] + 1] == T[i - p[i] - 1]) {
++p[i];
if(p[i] > maxLen){
maxLen = p[i];
firstIndex = (i - 1 - p[i]) / 2;
}
}
if(i + p[i] > R){
C = i;
R = i + p[i];
}
}
return s.substr(firstIndex, maxLen);
}
};

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

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

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

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

随机推荐

  1. ROS 使用自带和usb摄像头获取图像

    笔记本自带的摄像头的设备号一般为/dev/video0 第一步:安装Webcam 驱动 $ sudo apt-get install git-core $ cd ~/catkin_ws/src $ g ...

  2. 通过top命令发现plymouthd进程cpu负载达到近100% 解决办法

    最近几天一直遇到服务器cpu100%, 通过top命令发现plymouthd进程cpu负载达到近100% 解决方法:打开 /boot/grub/menu.lst , 去掉 “rhgb quiet”这两 ...

  3. eclipse 执行out.request()方法提示out cannot be resolved

    添加代码:PrintWriter out = response.getWriter(); 支持中文:response.setContentType("text/html;charset=ut ...

  4. ajaxsearch要点1

    ajaxsearch中必须将form的class定义为pagerForm,才能在foot中submit按钮得到值

  5. ubuntu auto install update

    sudo apt-get update sudo apt-get dist-upgrade 32bit mode sudo dpkg --add-architecture i386

  6. UltraISO制作大于4G文件的光盘映像可启动U盘

    1.使用常规方法 制作 u盘启动 启动-->写入硬盘映像-->写入 2.制作成功后U盘 是FAT32格式 对于FAT32文件系统,其缺点不能存储超过4G的文件,而对于NTFS文件系统,则没 ...

  7. 拿到新机器,进行初始化和部署Nginx的过程

    1. 在/etc/ansbile/hosts中添加主机init 2. 在sysinit.yml中修改要初始化的机器:   hosts: init 3. 设置不检查key      export ANS ...

  8. ios网络学习------4 UIWebView的加载本地数据的三种方式

    ios网络学习------4 UIWebView的加载本地数据的三种方式 分类: IOS2014-06-27 12:56 959人阅读 评论(0) 收藏 举报 UIWebView是IOS内置的浏览器, ...

  9. Windows下利用py2exe生成静默运行的命令行程序

    py2exe是python的第三方库,可以利用它将你的python脚本编译成可执行文件(exe),而在实际的开发过程中生成的dos窗口很影响用户体验,建议按以下方式让exe静默运行. 首先将你的pyt ...

  10. Caffe 源碼閱讀(一) Blob.hpp

    Blob 四維度(N K H W) N : SGD 一次 mini-batch 個數 K : 如果是圖片表示圖片通道數 如果是中間結果 則理解爲 feature map 個數 H.W : 如果是圖片理 ...