动态规划
-
确定dp数组下标及含义:
dp[i][j] s[i] 到s[j]是否为回文。是回文 dp[i][j]即为true -
确定递推公式
- 首先保证j大于等于i。当i和j相等。例:a。 必为回文 dp[i][j]=true
- i和j相差为1 s[i]=s[j]时 例:aa 也为回文 dp[i][j]=true
- i和j相差大于1时, 例: abcba。 计算dp[i+1][j-1]
if (s[i] == s[j]) {
if (j - i <= 1) { // 情况一 和 情况二
result++;
dp[i][j] = true;
} else if (dp[i + 1][j - 1]) { // 情况三
result++;
dp[i][j] = true;
}
}
3.初始化dp数组
将dp数组初始化为false,遇到符合回文字符串的位置设置为true,就可以避免重复筛选
4.确定dp数组遍历顺序
从下到上,从左到右。因为要用到dp[i + 1][j - 1]就必须先计算
for(let i=s.length-1;i>=0;i--){
//从下到上
for(let j=i;j<s.lenth;j++){//从左至右
if (s[i] == s[j]) {
if (j - i <= 1) { // 情况一 和 情况二
result++;
dp[i][j] = true;
} else if (dp[i + 1][j - 1]) { // 情况三
result++;
dp[i][j] = true;
}
}
}
}
5.打印dp检查结果
完整代码:
/**
* @param {string} s
* @return {number}
*/
var countSubstrings = function(s) {
let dp=new Array(s.length).fill(0),
result=0;
for(let i=0;i<dp.length;i++){
dp[i]=new Array(s.length).fill(0)
}
for(let i=s.length;i>=0;i--){
for(let j=i;j<s.length;j++){
if(s[i]==s[j]){
if(j-i<=1){
dp[i][j]=true;
result++;
}else if(dp[i+1][j-1]){
dp[i][j] = true;
result++
}
}
}
}
return result;
};