题目描述
给定一个字符串,你的任务是计算这个字符串中有多少个回文子串。
具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被视作不同的子串。
示例
示例1
输入:"abc"
输出:3
解释:三个回文子串: "a", "b", "c"
示例2
输入:"aaa"
输出:6
解释:6个回文子串: "a", "a", "a", "aa", "aa", "aaa"
解决思路
方法1 暴力破解
我们用ababa做例子, 对字符串做遍历,i 表示字符串的第n个数
i = 0, 字符a, 判断一下是否是回文,是的话count + 1。 此时我们保留上一次的字符['a']i = 1, 字符b, 此时我们对上一次字符数组的所有子串都添加b, 注意这里也要加上自身b, 也就是['b', 'ab']去判断一下是否是回文,此时再将上面数组保留下来。i = 2, 字符c, 我们继续做上面的操作, 先记录自身c, 再对上面保留下来的字符做c字符添加,也就是['c', 'bc', 'abc'], 对数组做回文判断,如此类推
我们总结一下,看下每次操作的数组
['a']['b', 'ab']['c', 'bc', 'abc']['b', 'cb', 'bcb', 'abcb'],['a', 'ba', 'cba', 'bcba', 'abcb']
// 完整代码
/**
* @param {string} s
* @return {number}
*/
var countSubstrings = function(s) {
let count = 0;
let length = s.length;
if(length === 0) {
return count
}
let prev = [s[0]];
count = 1;
for(let i = 1; i < length; i++) {
let current = [s[i]];
count++;
for(let j = 0; j < prev.length; j++) {
let temp = prev[j] + s[i];
if(ishuiwen(temp)) {
count++;
}
current.push(temp);
}
prev = current;
}
return count;
};
var ishuiwen = function(s) {
let start = 0;
let end = s.length - 1;
while(start < end) {
let ss = s[start];
let es = s[end];
if(ss !== es) {
return false
}
start++;
end--
}
return true
}
方法二 动态规划
上面 s[i][j] 指的是 s[i:j] 的子串, 比如 i = 1, j = 3, 以ababa 例子, s[i:j] => s[1:3] 就是字符串中的bab