想到动规的原因:
1. dp数组的含义
下标:i 到 j 的字符串中
值:i 到 j 的字符串中回文字符串的个
2. 递推公式
if(s[i] == s[j]) // 当前字符串相等
{
if(j - i <= 1) // i 到 j 之间只有一个或者两个字符串
{
dp[i][j] = true;
res++;
}
// i 到 j 之间有三个或及其以上的字符串
else if(dp[i + 1][j - 1]) // 这就需要依靠之前的字符串是否为回文字符串
{
dp[i][j] = true;
res++;
}
}
3. 初始化
全部初始化成 fasle,因为一开始还没开始匹配
4. 遍历顺序
递推公式中,有 dp[i + 1][j - 1] ,这个是在 dp [ i ][ j ] 的左下方,所以需要从下往上,从左往右遍历,以保证每次推导的都是有依据的值,而不是一开始被初始化的值。
class Solution {
public:
int countSubstrings(string s) {
vector<vector<bool>> dp(s.size(), vector<bool>(s.size(), false));
int res = 0;
for(int i = s.size() - 1; i >= 0; i--)
{
for(int j = i; j < s.size(); j++)
{
if(s[i] == s[j])
{
if(j - i <= 1)
{
dp[i][j] = true;
res++;
}
else if(dp[i + 1][j - 1])
{
dp[i][j] = true;
res++;
}
}
}
}
return res;
}
};