题目描述
给定一个字符串 s,你可以从中选出任意长度大于等于 2 的子串,并将这些子串按任意顺序连接起来。返回所有可能的结果。
注意:你可以以任意顺序返回答案。
示例 1:
输入:s = "abc" 输出:3 解释:三个回文子串: "a", "b", "c"
示例 2:
输入:s = "aaa" 输出:6 解释:6个回文子串: "a", "a", "a", "aa", "aa", "aaa"
提示:
- 1 <= s.length <= 1000
- s仅由小写英文字母组成
解法
根据题目描述,我们需要找出所有可能的回文子串。首先,我们可以通过枚举子串的方式来判断每个子串是否为回文串。具体来说,我们枚举子串的左右边界 l 和 r,满足 0 <= l <= r < len(s),如果子串 s[l, r]s[l,r] 是回文串,那么只要把该子串记录下来即可。
判断回文串可以使用双指针的方法。具体地,两个指针分别指向子串的左右两端,每次判断左右对应的字符是否相同,然后同时向中间移动指针,直到两个指针相遇或者交错。
代码如下:
function countSubstrings(s: string): number {
let count = 0;
for (let i = 0; i < s.length; i++) {
for (let j = i; j < s.length; j++) {
if (isPalindrome(s, i, j)) {
count++;
}
}
}
return count;
}
function isPalindrome(s: string, left: number, right: number): boolean {
while (left < right) {
if (s[left] !== s[right]) {
return false;
}
left++;
right--;
}
return true;
}
复杂度分析
时间复杂度:O(n^3),其中 n 是字符串的长度。枚举子串需要 O(n^2) 的时间,判断每个子串是否为回文串需要 O(n) 的时间。
空间复杂度:O(1)。我们只需要常数的空间存放若干变量。
还有一种的解法
function countSubstrings(s: string): number {
let res = 0;
for (let i = 0; i < s.length; i++) {
// 奇数长度回文串
let l = i, r = i;
while (l >= 0 && r < s.length && s[l] === s[r]) {
res++;
l--;
r++;
}
// 偶数长度回文串
l = i;
r = i + 1;
while (l >= 0 && r < s.length && s[l] === s[r]) {
res++;
l--;
r++;
}
}
return res;
}