1. Longest Palindromic Substring ( 最长回文子串 )
要求: 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 ( 最长回文子串 )的更多相关文章
- Leetcode 5. Longest Palindromic Substring(最长回文子串, Manacher算法)
Leetcode 5. Longest Palindromic Substring(最长回文子串, Manacher算法) Given a string s, find the longest pal ...
- LeetCode:Longest Palindromic Substring 最长回文子串
题目链接 Given a string S, find the longest palindromic substring in S. You may assume that the maximum ...
- lintcode :Longest Palindromic Substring 最长回文子串
题目 最长回文子串 给出一个字符串(假设长度最长为1000),求出它的最长回文子串,你可以假定只有一个满足条件的最长回文串. 样例 给出字符串 "abcdzdcab",它的最长回文 ...
- [leetcode]5. Longest Palindromic Substring最长回文子串
Given a string s, find the longest palindromic substring in s. You may assume that the maximum lengt ...
- 5. Longest Palindromic Substring(最长回文子串 manacher 算法/ DP动态规划)
Given a string s, find the longest palindromic substring in s. You may assume that the maximum lengt ...
- [LeetCode] 5. Longest Palindromic Substring 最长回文子串
Given a string s, find the longest palindromic substring in s. You may assume that the maximum lengt ...
- 【LeetCode】5. Longest Palindromic Substring 最长回文子串
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 公众号:负雪明烛 本文关键词:最长回文子串,题解,leetcode, 力扣,python ...
- 【翻译】Longest Palindromic Substring 最长回文子串
原文地址: http://articles.leetcode.com/2011/11/longest-palindromic-substring-part-i.html 转载请注明出处:http:// ...
- LeetCode5. Longest Palindromic Substring 最长回文子串 4种方法
题目链接:https://leetcode.com/problems/longest-palindromic-substring/ 题意很简单,就是求一个字符串得最长子串,这里的子串指连续的. 本文给 ...
随机推荐
- linux kernel tainted
日志中会有一些信息: dmesg | grep -i tainted 具体代码可以通过proc看到: cat /proc/sys/kernel/tainted 数字的意义: tainted: Non- ...
- JavaScript数组方法总结
由于最近都在freecodecamp上刷代码,运用了很多JavaScript数组的方法,因此做了一份关于JavaScript教程的整理,具体内容如下: 一.普通方法 1.join() 将数组元素连接在 ...
- UE4 异步资源加载
http://blog.csdn.net/pizi0475/article/details/48178861 http://blog.sina.com.cn/s/blog_710ea1400102vl ...
- NOI Linux JAVA
右键open with another application 里输javaws 按ctrl+shift+del,调出火狐内置的清除最近的历史记录工具(或者按alt键弹出菜单,工具->清空最近历 ...
- C# 计算时间差 用timespan函数
TimeSpan 结构 表示一个时间间隔. 命名空间:System 程序集:mscorlib(在 mscorlib.dll 中) 1.DateTime值类型代表了一个从公元0001年1月1日0点0分 ...
- SQL 函数集锦
..STUFF()用另一子串替换字符串指定位置.长度的子串.STUFF (<character_expression1>, <start_ position>, <len ...
- IOS7 ~ Xcode5 制作 framework
一.Framework 简介(Introduction to Framework Programming Guide) Mac OS X 扩展了 framework 的功能,让我们能够利用它来共享代码 ...
- CI框架引入外部css和js文件
首先在项目根目录下建立assets文件夹,在这个文件夹下再建立css和js文件夹分别放置css和js文件 然后,在项目根目录下建立.htaccess文件 内容如下: RewriteEngine on ...
- 问:Linux下Chrome标题栏中文乱码
From:http://blog.csdn.net/loveaborn/article/details/29579787 在使用Linux的时候你会遇到一些奇奇怪怪的问题,不过,你会在解决这些问题的过 ...
- 关于 Unix 用户权限及进程权限及 Saved set-user-id
最近在看APUE,看到3.14节,fcntl的时候#include <fcntl.h>int fcntl(int fd, int cmd, .../* int arg */);出错返回-1 ...