[译]最长回文子串(Longest Palindromic Substring) Part I
2014-12-14 16:05
435 查看
[译]最长回文子串(Longest Palindromic Substring) Part I
英文原文链接在(http://leetcode.com/2011/11/longest-palindromic-substring-part-i.html)
+BIT祝威+悄悄在此留下版了个权的信息说:
问题:给定字符串S,求S中的最长回文子串。
这个有趣的问题常常在面试中出现。为什么呢?因为解决办法有很多种。单单我知道的就有5种。你能解决这个问题吗?来Online Judge试试看吧!
看起来有道理的样子。用实例检验下。
例如S=”caba”,S’=”abac”。
S和S’的最长公共子串是”aba”,确实是S的最长回文子串。
再看个例子。
S=”abacdfgdcaba”,S’=”abacdgfdcaba”。
S和S’的最长公共子串是”abacd”,不过很明显这不是回文。
总结起来就是:
定义二维数组P[i,j]用以表示Si…Sj是回文(true)或不是回文(false)
那么可知P[i,j] = (P[i + 1, j - 1] && Si ==Sj)
初始条件是:P[i, i]=true,P[i, i + 1] = (Si == Si+1)
这个DP法的思路就是,首先可以知道单个字符和两个相邻字符是否回文,然后检测连续三个字符是否回文,然后四个。。。
此算法时间复杂度O(N2),空间复杂度O(N2)。伪代码如下。
提问:空间复杂度还能再改进吗?
回文的特点,就是中心对称。对于有N个字符的字符串S,只有2N-1个中心。
为何是2N-1?因为两个字符之间的空档也可以是一个中心。例如”abba”的两个b中间就是一个中心。
围绕一个中心检测回文需要O(N)时间,所以总的时间复杂度是O(N2)。
+BIT祝威+悄悄在此留下版了个权的信息说:
PS:“中心检测法”是我胡诌的名字。
英文原文链接在(http://leetcode.com/2011/11/longest-palindromic-substring-part-i.html)
+BIT祝威+悄悄在此留下版了个权的信息说:
问题:给定字符串S,求S中的最长回文子串。
这个有趣的问题常常在面试中出现。为什么呢?因为解决办法有很多种。单单我知道的就有5种。你能解决这个问题吗?来Online Judge试试看吧!
提示
首先你要知道回文是什么。回文就是从左右两边读都一样的字符串。例如”aba”是回文,”abc”不是回文。一个常见的错误
有人很快会想到这样一个方法。这个方法有缺陷,不过很容易修正。翻转S成为S’。查找S和S’最长公共子串,就是S的最长回文子串。 |
例如S=”caba”,S’=”abac”。
S和S’的最长公共子串是”aba”,确实是S的最长回文子串。
再看个例子。
S=”abacdfgdcaba”,S’=”abacdgfdcaba”。
S和S’的最长公共子串是”abacd”,不过很明显这不是回文。
暴力穷举法O(N3)
最简单的就是暴力穷举(Brute Force)对每个start和end位置的子串进行检测,判断其是否回文。显然有C(N,2)(组合)个子串。检测每个子串都需要O(N)的时间,所以此方法的时间复杂度为O(N3)。动态规划法O(N2)时间O(N2)空间
我们可以用动态规划(Dynamic Programming即DP)法对暴力穷举法进行改进。记住,诀窍就是避免重复计算(即重复检测同一子串)。考虑这个例子”ababa”。如果我们已经检测过”bab”是回文,那么只需判断一下最左右的两个字符(即两个a)是否相同即可判定”ababa”是否回文了。总结起来就是:
定义二维数组P[i,j]用以表示Si…Sj是回文(true)或不是回文(false)
那么可知P[i,j] = (P[i + 1, j - 1] && Si ==Sj)
初始条件是:P[i, i]=true,P[i, i + 1] = (Si == Si+1)
这个DP法的思路就是,首先可以知道单个字符和两个相邻字符是否回文,然后检测连续三个字符是否回文,然后四个。。。
此算法时间复杂度O(N2),空间复杂度O(N2)。伪代码如下。
string longestPalindromeDP(string s) { int n = s.length(); int longestBegin = 0; int maxLen = 1; bool table[1000][1000] = {false}; for (int i = 0; i < n; i++) { table[i][i] = true; } for (int i = 0; i < n-1; i++) { if (s[i] == s[i+1]) { table[i][i+1] = true; longestBegin = i; maxLen = 2; } } for (int len = 3; len <= n; len++) { for (int i = 0; i < n-len+1; i++) { int j = i+len-1; if (s[i] == s[j] && table[i+1][j-1]) { table[i][j] = true; longestBegin = i; maxLen = len; } } } return s.substr(longestBegin, maxLen); }
提问:空间复杂度还能再改进吗?
更简单的算法O(N2)时间O(1)空间
下面介绍一个O(N2)时间O(1)空间的算法。回文的特点,就是中心对称。对于有N个字符的字符串S,只有2N-1个中心。
为何是2N-1?因为两个字符之间的空档也可以是一个中心。例如”abba”的两个b中间就是一个中心。
围绕一个中心检测回文需要O(N)时间,所以总的时间复杂度是O(N2)。
string expandAroundCenter(string s, int c1, int c2) { int l = c1, r = c2; int n = s.length(); while (l >= 0 && r <= n-1 && s[l] == s[r]) { l--; r++; } return s.substr(l+1, r-l-1); } string longestPalindromeSimple(string s) { int n = s.length(); if (n == 0) return ""; string longest = s.substr(0, 1); // a single char itself is a palindrome for (int i = 0; i < n-1; i++) { string p1 = expandAroundCenter(s, i, i); if (p1.length() > longest.length()) longest = p1; string p2 = expandAroundCenter(s, i, i+1); if (p2.length() > longest.length()) longest = p2; } return longest; }
+BIT祝威+悄悄在此留下版了个权的信息说:
PS:“中心检测法”是我胡诌的名字。
提问O(N)
是否存在O(N)时间的算法?当然有!不过理解起来有点费劲,我们下回分解。相关文章推荐
- LeetCode:5_Longest Palindromic Substring | 最长的回文子串 | Medium
- LeetCode-5-Longest Palindromic Substring 最长回文子串DP
- 求最长回文子串 - leetcode 5. Longest Palindromic Substring
- 最长回文子串(Longest Palindromic Substring )
- Longest Palindromic Substring(最长回文子串)
- 【LeetCode刷题】最长回文子串Longest Palindromic Substring(java)
- Longest Palindromic Substring-----最长回文子串
- LeetCode题库解答与分析——#5.最长回文子串LongestPalindromicSubstring
- 最长回文子串-LeetCode 5 Longest Palindromic Substring
- 最长回文子串(Longest Palindromic Substring)
- leetcode-5. Longest Palindromic Substring(寻找最长回文子串)
- LeetCode-5 Longest Palindromic Substring(求最长回文子串)
- 最长回文子串(Longest Palindromic Substring)
- leetcode Longest Palindromic Substring最长回文子串
- 【LeetCode】Longest Palindromic Substring && 【九度】题目1528:最长回文子串(腾讯2013年实习生招聘二面面试题)
- 【翻译】Longest Palindromic Substring 最长回文子串
- 最长回文子串(Longest Palindromic Substring)
- LeetCode 5 Longest Palindromic Substring(最长回文子串,暴力剪枝/DP/曼彻斯特算法)
- leetcode05 Longest Palindromic Substring 最长回文子串
- Longest Palindromic Substring 最长回文子串