最长回文子串
https://leetcode.com/problems/longest-palindromic-substring/
题目1:求最长回文子串
参考答案:
class Solution {
public:
string longestPalindrome(string s) {
int size=s.size();
//处理特例
if(size==0)return "";
if(size==1)return s;
//二维vector的初始化
vector<vector<int>> dp(size,vector<int>(size,0));
for(int i=0;i<size;i++){
dp[i][i]=1;
}
int start=0,maxLen=1;
for(int len=2;len<=size;len++){//遍历所有可能的长度
for(int i=0;i<size&&i-1+len<size;i++){//遍历所有可能的起点
if(s[i]==s[i-1+len]){ //相等才需要继续判断,不等的话保留为0,即非回文串
//长度为2时没有内部子串需要判断了,直接判断为1
dp[i][i-1+len]=len==2?1:dp[i+1][i-2+len];
if(dp[i][i-1+len]&&len>maxLen){
maxLen=len;
start=i;
}
}
}
}
return s.substr(start,maxLen);
}
};
题目2:求回文子串数量
参考答案:
class Solution {
public:
int countSubstrings(string s) {
int len=s.size();
if(len<=1)return len;
vector<vector<bool>> dp(len,vector<bool>(len,false));
//bool dp[len][len];
// 初始化len=1的状态并设置对应的结果,此处由于有len个长度为1的回文子串,故nums=len
for(int i=0;i<len;i++)dp[i][i]=true;
int nums=len;
// 状态转移求出len>1的状态
for(int n=2;n<=len;n++){
for(int t=0;t<len && t+n-1<len;t++){
int e=t+n-1;
if(n==2){
dp[t][e]=s[t]==s[e];
}else{
dp[t][e]=s[t]==s[e]?dp[t+1][e-1]:false;
}
if(dp[t][e])nums++;
}
}
return nums;
}
};
最长回文子序列
https://leetcode.com/problems/longest-palindromic-subsequence/
class Solution {
public:
int longestPalindromeSubseq(string s) {
int n = s.size();
vector<vector<int>> dp(n+1,vector<int>(n));
for(int i=0;i<n;i++) dp[1][i]=1;
for(int i=2;i<=n;i++){ //length
for(int j=0;j<n-i+1;j++) {//start index
dp[i][j] = s[j]==s[i+j-1]?2+dp[i-2][j+1]:max(dp[i-1][j],dp[i-1][j+1]);
}
}
return dp[n][0];
}
};
对比
忽略两个题目对于返回结果的不同要求(前者返回最长的结果,后者返回最长的结果对应的长度即可)。
dp数组的定义的区别:
最长回文子串:dp[i][j]
表示的是string s
中从i
到j
的子串(用python语法就是s[i:j+1]
)是否为回文子串。
最长回文子序列:dp[i][j]
表示的是长度为i
起点为j
的子串(即s[j:j+i-1]
)的最长回文子序列的长度。