暴力求解法
#include <iostream>
#include <string>
#include <vector>
#include <cstdlib>
#include <ctime>
#include <cmath>
using namespace std;
#ifndef _SOLUTION_H
#define _SOLUTION_H
/**思路:
从回文串的对称点开始,依次向左向右比较,不相同的时候停止遍历,直到找出最大的长度的回文子串。
* (1)回文子串长度为奇数:对称点只有一个字符
* (2)回文子串长度为偶数:对称点有两个字符
时间复杂度为O(n^2):对称点的数量为O(n),每次查找的时间也为O(n),所有总时间复杂度为O(n^2) */
class Solution {
public:
string longestPalindrome(string s) {
//字符串的长度
int len = s.size();
if (len == 0) return s;
//保留最长回文串
string resultStr = "";
//回文子串长度为奇数,:对称点只有一个字符的情况
for (int i=0; i<len; ++i){
// i 为对称点
int left = i;//左
int right = i;//右
//向左向右遍历,直到发现不相同的时候停止
while (left > 0 && right < len - 1 && s[left - 1] == s[right + 1]){
--left;
++right;
}
//比较,更新最长回文串
if (right - left + 1 > resultStr.size()){
resultStr = s.substr(left, right - left + 1);
}
}
//回文子串长度为偶数:对称点有两个字符
for (int i = 0; i < len - 1; ++i){
if (s[i] == s[i+1]){//两个对称点相同,才有继续遍历的意义
int left = i;
int right = i+1;
//向左向右遍历,直到发现不相同的时候停止
while (left > 0 && right < len - 1 && s[left - 1] == s[right + 1]){
--left;
++right;
}
//比较,更新最长回文串
if (right - left + 1 > resultStr.size()){
resultStr = s.substr(left, right - left + 1);
}
}
}
return resultStr;
}
};
#endif
方法2 DP(Dynamic Programming)方法
我们维护一个二维数组dp,其中dp[i][j]表示字符串区间[i,j]是否为回文串,当i==j时,只有一个字符,肯定是回文串,如果i=j+1,说明是相邻字符串,此时需要判断s[j]是否等于s[j],如果i=j+1,说明是相邻字符,此时需要判断s[i]是否等于s[j].如果i和j不相邻,需要除了判断s[i]s[j]相等之外dp[j+1][i-1]若为真,就是回文串。
可以写出如下递推式子:
dp[i,j] = 1
if i == j
if j = i + 1& s[i] == s[j]
if j-i>=2&s[i]==s[j]&dp[j+1][i-1]==1
不断更新索引,找出最长len.
#include <iostream>
#include <string>
#include <vector>
#include <cstdlib>
#include <ctime>
#include <cmath>
using namespace std;
#ifndef _SOLUTION_H
#define _SOLUTION_H
// DP
class Solution {
public:
string longestPalindrome(string s) {
int dp[s.size()][s.size()] = {0}, left = 0, right = 0, len = 0;
for (int i = 0; i < s.size(); ++i) {
for (int j = 0; j < i; ++j) {
dp[j][i] = (s[i] == s[j] && (i - j < 2 || dp[j + 1][i - 1]));
if (dp[j][i] && len < i - j + 1) {
len = i - j + 1;
left = j;
right = i;
}
}
dp[i][i] = 1;
}
return s.substr(left, right - left + 1);
}
};
#endif
Manacher’s Algorithm
时间复杂度为O(n)
.