1.最长回文子串
给你一个字符串 s,找到 s 中最长的回文子串。
考察知识点:动态规划
用 P(i,j)表示字符串s的第i到第j个字母组成的串是否为回文串,状态转移方程为
class Solution {
public:
string longestPalindrome(string s) {
vector<vector<int>> dp(s.length(), vector<int>(s.length()));
string ans;
for (int L = 0; L < s.length(); ++L)
{
for (int i = 0; i + L < s.length(); ++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.length())
ans = s.substr(i, L + 1);
}
}
return ans;
}
};
2.回文数
给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false 。
回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。例如,121 是回文,而 123 不是。
class Solution {
public:
bool isPalindrome(int x) {
if(x<0) return false;
int res=0,num=x;
while(x)
{
if(res>INT_MAX/10||(res==INT_MAX&&x%10>INT_MAX%10))
return false;
res=res*10+x%10;
x/=10;
}
return res==num;
}
};
3.验证回文串
给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。
说明:本题中,我们将空字符串定义为有效的回文串。
class Solution {
public:
bool isPalindrome(string s) {
string str;
for (char ch: s)
{
if (isalnum(ch))
str += tolower(ch);
}
string str_rev(str.rbegin(), str.rend());
return str_rev == str;
}
};
4.分割回文串
给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是 回文串 。返回 s 所有可能的分割方案。
回文串是正着读和反着读都一样的字符串。
考察知识点:动态规划、双指针
class Solution {
public:
vector<vector<bool>> f;
vector<vector<string>> ans;
vector<string> res;
vector<vector<string>> partition(string s) {
int n=s.size();
f.assign(n,vector<bool>(n,true));
for(int i=n-1;i>=0;--i)
{
for(int j=i+1;j<n;++j) //**
{
f[i][j]=f[i+1][j-1]&(s[i]==s[j]);
}
}
dfs(s,0);
return ans;
}
void dfs(string s,int i){
if(i>=s.size())
{
ans.push_back(res);
return;
}
for(int j=i;j<s.size();++j) //**
{
if(f[i][j]) //*
{
res.push_back(s.substr(i,j-i+1));
dfs(s,j+1); //*
res.pop_back();
}
}
}
};
5.分割回文串 II
给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是回文。
返回符合要求的最少分割次数 。
考察知识点:动态规划
class Solution {
public:
int minCut(string s) {
int n=s.size();
vector<vector<bool>> f(n,vector<bool>(n,true));
for (int i=n-1; i >= 0; --i)
{
for(int j=i+1;j<n;++j)
{
f[i][j]=f[i+1][j-1]&&(s[i]==s[j]); //*
}
}
vector<int> num(n,INT_MAX);
for(int i=0;i<n;++i)
{
if(f[0][i])
num[i]=0;
else{
for(int j=0;j<i;++j)
{
if(f[j+1][i])
num[i]=min(num[i],num[j]+1); //*
}
}
}
return num[n-1];
}
};