自学笔记
最长回文子串
动态规划:
class Solution {
public:
string longestPalindrome(string s) {
//其他类型的动态规划(稍加优化)
if(s.empty()) return "";
int n=s.size();
vector<vector<int>>dp(n,vector<int>(n,0));
string longString=s.substr(0, 1);
for(int i = 0; i < n; i++) dp[i][i] = 1;
for(int i = n - 1; i >= 0; i--) {
for(int j = i + 1; j < n; j++) {
if(s[i] == s[j] && (dp[i + 1][j - 1] > 0 || j == i + 1)) {
dp[i][j] = dp[i + 1][j - 1] + 2;
if(j - i + 1 > longString.size()) {
longString = s.substr(i, j - i + 1);
}
}
}
}
return longString;
}
};
中心扩散:
class Solution {
public:
string longestPalindrome(string s) {
// 特判
int size = s.size();
if (size < 2) {
return s;
}
int maxLen = 1;
string res = s.substr(0, 1);
for (int i = 0; i < size - 1; i++) {//最后一位字符不用扩散
string oddStr = centerSpread(s, i, i); //奇数
string evenStr = centerSpread(s, i, i + 1); //偶数
string maxLenStr = oddStr.size() > evenStr.size() ? oddStr : evenStr;
if (maxLenStr.length() > maxLen) {
maxLen = maxLenStr.size();
res = maxLenStr;
}
}
return res;
}
private:
string centerSpread(string s,int left,int right){
// left = right 的时候,此时回文中心是一个空隙,向两边扩散得到的回文子串的长度是奇数
// right = left + 1 的时候,此时回文中心是一个字符,向两边扩散得到的回文子串的长度是偶数
int size=s.size();
int i=left;
int j=right;
while(i>=0&&j<size){
if(s[i]==s[j]){
i--;
j++;
}
else break;
}
return s.substr(i + 1, j - i - 1);
}
回文子串
动态规划:
class Solution {
public:
int countSubstrings(string s) {
int ret=0;
int n=s.size();
if(n<2)return n;
vector<vector<int>>dp(n,vector<int>(n,0));
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;
ret++;
}
else if(l==1){
dp[i][j] = (s[i] == s[j]);
ret+=(s[i]==s[j]);
}
else{
dp[i][j] = (s[i] == s[j] && dp[i + 1][j - 1]);
ret+=(s[i] == s[j] && dp[i + 1][j - 1]);
}
}
}
return ret;
}
};
中心扩散:
class Solution {
public:
int countSubstrings(string s) {
int size=s.size();
if(size<2)return size;
int ret=0;
for(int i=0;i<size;i++){
ret+=centerSpread(s,i,i)+centerSpread(s,i,i+1);
}
return ret;
}
private:
int centerSpread(string s,int left,int right){
// left = right 的时候,此时回文中心是一个空隙,向两边扩散得到的回文子串的长度是奇数
// right = left + 1 的时候,此时回文中心是一个字符,向两边扩散得到的回文子串的长度是偶数
int size=s.size();
int count=0;
int i=left;
int j=right;
while(i>=0&&j<size){
if(s[i]==s[j]){
i--;
j++;
count++;
}
else break;
}
return count;
}
};
马拉车算法
比较复杂,自己就不做笔记了,可以看别人的博客