回文数字和字符串处理
暴力解法
时间复杂度太高,超时。
class Solution {
public:
bool isPalindrome(string s){
int n = s.length();
for(int i = 0; i < n / 2; i++){
if(s[i] != s[n-i-1]){
return false;
}
}
return true;
}
string longestPalindrome(string s) {
if(s.length() == 1){return s;}
int n = s.length();
string ans="";
int max = 0;
for(int i = 0; i < n; i++){
for(int j = 0; j <= n; j++){
string temp = s.substr( i , j);
int temp_n = temp.length();
if(isPalindrome(temp) && temp_n > max){
ans = temp;
max = temp_n > max ? temp_n : max;
}
}
}
return ans;
}
};
中心扩散法
有2(n-1)个中心,时间复杂度是O(n)。空间复杂度是O(1)。
//中间扩散法
class Solution {
public:
int expandAroundCenter(string s, int left, int right){
int l = left;
int r = right;
while(l >= 0 && r < s.length() && s[l] == s[r]){
l--;
r++;
}
return r-l-1;
}
string longestPalindrome(string s) {
int n = s.length();
if(n < 2){
return s;
}
int start = 0, end = 0;
for(int i = 0; i < n - 1; i++){
int len1 = expandAroundCenter(s, i, i);
int len2 = expandAroundCenter(s, i, i + 1);
int max_len = len1 > len2 ? len1 : len2;
if(max_len > end - start){
start = i - (max_len - 1) / 2;
end = i + max_len / 2;
}
}
return s.substr(start, end-start+1);
}
};
动态规划法
状态:dp[i] [j]表示子串s[i·····j]是否是回文子串。
转移方程:dp[i] [j] = (s[i] == s[j] ) and dp[i+1] [j-1]
边界条件:j - 1 - (i + 1)+ 1 < 2,整理得 j - i < 3
初始化: dp[i] [j] = true
输出:在得到一个状态的值为True的时候,记录起始位置和长度,填表完成以后再截取
class Solution {
public:
string longestPalindrome(string s) {
int n = s.size();
vector<vector<int>> dp(n, vector<int>(n));
string ans;
for (int l = 0; l < n; ++l) {
for (int i = 0; i + l < n; ++i) {
int j = i + l;
if (l == 0) {
dp[i][j] = 1;
}
else if (l == 1) {
dp[i][j] = (s[i] == s[j]);
}
else {
dp[i][j] = (s[i] == s[j] && dp[i + 1][j - 1]);
}
if (dp[i][j] && l + 1 > ans.size()) {
ans = s.substr(i, l + 1);
}
}
}
return ans;
}
};
Manacher算法
俗称马拉车算法,专门用来查找最长回文子串的算法,时间复杂度是O(n)。
将原始字符串进行预处理,在预处理字符串上执行动态规划和中心扩散算法。
太难了,我还没看懂。