1.回文子串
代码:
class Solution {
public:
int countSubstrings(string s) {
int n = s.size();
vector<vector<bool>> dp(n, vector<bool>(n));
int ret = 0;
for(int i = n - 1; i >= 0; i--)
{
for(int j = i; j < n; j++)
{
if(s[i] == s[j])
dp[i][j] = i + 1 < j ? dp[i + 1][j - 1] : true;
if(dp[i][j])
ret++;
}
}
return ret;
}
};
2.最长回文子串
代码:
class Solution {
public:
string longestPalindrome(string s) {
int n = s.size();
vector<vector<bool>> dp(n, vector<bool>(n));
int len = 1, begin = 0;
for(int i = n - 1; i >= 0; i--)
{
for(int j = i; j < n; j++)
{
if(s[i] == s[j])
dp[i][j] = i + 1 < j ? dp[i + 1][j - 1] : true;
if(dp[i][j] && j - i + 1 > len)
begin = i, len = j - i + 1;
}
}
return s.substr(begin, len);
}
};
3.分割回文串iv
代码:
class Solution {
public:
bool checkPartitioning(string s) {
//用dp表把所有的子串是否是回文预处理一下
int n = s.size();
vector<vector<bool>> dp(n, vector<bool>(n));
for(int i = n - 1; i >= 0; i--)
for(int j = i; j < n; j++)
if(s[i] == s[j])
dp[i][j] = i + 1 < j ? dp[i + 1][j - 1] : true;
//枚举所有的第二个字符串的起始位置和结束位置
for(int i = 1; i < n - 1; i++)
for(int j = i; j < n - 1; j++)
if(dp[0][i - 1] && dp[i][j] && dp[j + 1][n - 1])
return true;
return false;
}
};
4.分割回文串ii
代码:
class Solution {
public:
int minCut(string s) {
// 预处理,统计所有子串是否是回文
int n = s.size();
vector<vector<bool>> isPal(n, vector<bool>(n));
for(int i = n - 1; i >= 0; i--)
for(int j = i; j < n; j++)
if(s[i] == s[j])
isPal[i][j] = i + 1 < j ? isPal[i + 1][j - 1] : true;
vector<int> dp(n, INT_MAX);
for(int i = 0; i < n; i++)
{
if(isPal[0][i]) dp[i] = 0;
else
{
for(int j = 1; j <= i; j++)
{
if(isPal[j][i])
dp[i] = min(dp[i], dp[j - 1] + 1);
}
}
}
return dp[n - 1];
}
};
5.最长回文子序列
代码:
class Solution {
public:
int longestPalindromeSubseq(string s) {
int n = s.size();
vector<vector<int>> dp(n, vector<int>(n));
for(int i = n - 1; i >= 0; i--)
{
dp[i][i] = 1;
for(int j = i + 1; j < n; j++)
{
if(s[i] == s[j]) dp[i][j] = dp[i + 1][j - 1] + 2;
else dp[i][j] = max(dp[i][j - 1], dp[i + 1][j]);
}
}
return dp[0][n - 1];
}
};
6.让字符串成为回文串的最少插入次数
代码:
class Solution {
public:
int minInsertions(string s) {
int n = s.size();
vector<vector<int>> dp(n, vector<int>(n));
for(int i = n - 1; i >= 0; i--)
{
for(int j = i + 1; j < n; j++)
{
if(s[i] == s[j]) dp[i][j] = dp[i + 1][j - 1];
else dp[i][j] = min(1 + dp[i + 1][j], 1 + dp[i][j - 1]);
}
}
return dp[0][n - 1];
}
};