647. 回文子串(双指针/动态规划)
方法一(双指针)
示例代码
class Solution {
public:
int help(string s,int l,int r){
int count=0;
while(l>=0&&r<s.length()&&(s[l]==s[r])){
l--;
r++;
count++;
}
return count;
}
int countSubstrings(string s) {
int len=s.length();
int res=0;
for(int i=0;i<len;i++){
//三个元素还可以做中心点呢。其实三个元素就可以由一个元素左右添加元素得到
//四个元素则可以由两个元素左右添加元素得到。
res+=help(s,i,i);//一个元素作为中心点
res+=help(s,i,i+1);//两一个元素作为中心点
}
return res;
}
};
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
效果展示
方法二(动态规划)
示例代码
class Solution {
public:
int countSubstrings(string s) {
int len=s.length();
//布尔类型的dp[i][j]:表示区间范围[i,j] (注意是左闭右闭)的子串是否是回文子串,如果是dp[i][j]为true,否则为false。
vector<vector<bool>> dp(len+1,vector<bool>(len+1,false));
int res=0;
//如果这矩阵是从上到下,从左到右遍历,那么会用到没有计算过的dp[i + 1][j - 1],也就是根据不确定是不是回文的区间[i+1,j-1],来判断了[i,j]是不是回文,那结果一定是不对的。
// 所以一定要从下到上,从左到右遍历,这样保证dp[i + 1][j - 1]都是经过计算的。
for(int i=len;i>0;i--){
//由于dp数组的定义得到的
for(int j=i;j<=len;j++){
if(s[i-1]==s[j-1]){
//情况一:下标i 与 j相同,同一个字符例如a,当然是回文子串
// 情况二:下标i 与 j相差为1,例如aa,也是回文子串
if(j-i<=1){
res++;
dp[i][j]=true;
}
// 情况三:下标:i 与 j相差大于1的时候
//例如cabac,此时s[i]与s[j]已经相同了,我们看i到j区间是不是回文子串就看aba是不是回文就可以了,那么aba的区间就是 i+1 与 j-1区间,这个区间是不是回文就看dp[i + 1][j - 1]是否为true。
else if(dp[i+1][j-1]){
res++;
dp[i][j]=true;
}
}
}
}
return res;
}
};
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
效果展示
5. 最长回文子串
示例代码
class Solution {
public:
string longestPalindrome(string s) {
int len=s.length();
//布尔类型的dp[i][j]:表示区间范围[i,j] (注意是左闭右闭)的子串是否是回文子串,如果是dp[i][j]为true,否则为false。
vector<vector<bool>> dp(len+1,vector<bool>(len+1,false));
int maxLen=1;
string maxStr="";
//如果这矩阵是从上到下,从左到右遍历,那么会用到没有计算过的dp[i + 1][j - 1],也就是根据不确定是不是回文的区间[i+1,j-1],来判断了[i,j]是不是回文,那结果一定是不对的。
// 所以一定要从下到上,从左到右遍历,这样保证dp[i + 1][j - 1]都是经过计算的。
for(int i=len;i>0;i--){
//由于dp数组的定义得到的
for(int j=i;j<=len;j++){
if(s[i-1]==s[j-1]){
//情况一:下标i 与 j相同,同一个字符例如a,当然是回文子串
// 情况二:下标i 与 j相差为1,例如aa,也是回文子串
if(j-i<=1){
dp[i][j]=true;
if(j-i+1>maxLen){
maxStr=s.substr(i-1,j-i+1);
maxLen=j-i+1;
}
}
// 情况三:下标:i 与 j相差大于1的时候
//例如cabac,此时s[i]与s[j]已经相同了,我们看i到j区间是不是回文子串就看aba是不是回文就可以了,那么aba的区间就是 i+1 与 j-1区间,这个区间是不是回文就看dp[i + 1][j - 1]是否为true。
else if(dp[i+1][j-1]){
dp[i][j]=true;
if(j-i+1>maxLen){
maxStr=s.substr(i-1,j-i+1);
maxLen=j-i+1;
}
}
}
}
}
string str=string(1,s[0]);
return maxLen==1?str:maxStr;
}
};
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
效果展示
一文教你精通C++中单个字符与字符串之间的相互转换(to_string函数并不能直接用于单个字符,因为 to_string是用于将数值类型转换为字符串的)
相似题目
LeetCode—516. 最长回文子序列(动态规划)