本文转自:http://www.cnblogs.com/TenosDoIt/p/3675788.html
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.
求字符串的最长回文子串
算法1:暴力解法,枚举所有子串,对每个子串判断是否为回文,复杂度为O(n^3)
算法2:删除暴力解法中有很多重复的判断。很容易想到动态规划,时间复杂度O(n^2),空间O(n^2),动态规划方程如下:
- dp[i][j] 表示子串s[i…j]是否是回文
- 初始化:dp[i][i] = true (0 <= i <= n-1); dp[i][i-1] = true (1 <= i <= n-1); 其余的初始化为false
- dp[i][j] = (s[i] == s[j] && dp[i+1][j-1] == true)
在动态规划中保存最长回文的长度及起点即可
1 class Solution {
2 public:
3 string longestPalindrome(string s) {
4 const int len = s.size();
5 if(len <= 1)return s;
6 bool dp[len][len];//dp[i][j]表示s[i..j]是否是回文
7 memset(dp, 0, sizeof(dp));
8 int resLeft = 0, resRight = 0;
9 dp[0][0] = true;
10 for(int i = 1; i < len; i++)
11 {
12 dp[i][i] = true;
13 dp[i][i-1] = true;//这个初始化容易忽略,当k=2时要用到
14 }
15 for(int k = 2; k <= len; k++)//枚举子串长度
16 for(int i = 0; i <= len-k; i++)//枚举子串起始位置
17 {
18 if(s[i] == s[i+k-1] && dp[i+1][i+k-2])
19 {
20 dp[i][i+k-1] = true;
21 if(resRight-resLeft+1 < k)
22 {
23 resLeft = i;
24 resRight = i+k-1;
25 }
26 }
27 }
28 return s.substr(resLeft, resRight-resLeft+1);
29 }
30 };
算法3:以某个元素为中心,分别计算偶数长度的回文最大长度和奇数长度的回文最大长度。时间复杂度O(n^2),空间O(1)
1 class Solution {
2 public:
3 string longestPalindrome(string s) {
4 const int len = s.size();
5 if(len <= 1)return s;
6 int start, maxLen = 0;
7 for(int i = 1; i < len; i++)
8 {
9 //寻找以i-1,i为中点偶数长度的回文
10 int low = i-1, high = i;
11 while(low >= 0 && high < len && s[low] == s[high])
12 {
13 low--;
14 high++;
15 }
16 if(high - low - 1 > maxLen)
17 {
18 maxLen = high - low -1;
19 start = low + 1;
20 }
21
22 //寻找以i为中心的奇数长度的回文
23 low = i- 1; high = i + 1;
24 while(low >= 0 && high < len && s[low] == s[high])
25 {
26 low--;
27 high++;
28 }
29 if(high - low - 1 > maxLen)
30 {
31 maxLen = high - low -1;
32 start = low + 1;
33 }
34 }
35 return s.substr(start, maxLen);
36 }
37 };
算法4:Manacher算法,时间复杂度O(n), 空间复杂度O(n)
该算法首先对字符串进行预处理,在字符串的每个字符前后都加入一个特殊符号,比如字符串 abcd 处理成 #a#b#c#d#,为了避免处理越界,在字符串首尾加上不同的两个特殊字符(c类型的字符串尾部不用加,因为自带‘