题目描述
给你一个字符串 s ,请你统计并返回这个字符串中 回文子串 的数目。
回文字符串 是正着读和倒过来读一样的字符串。
子字符串 是字符串中的由连续字符组成的一个序列。
具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被视作不同的子串。
样例描述
示例 1:
输入:s = "abc"
输出:3
解释:三个回文子串: "a", "b", "c"
示例 2:
输入:s = "aaa"
输出:6
解释:6个回文子串: "a", "a", "a", "aa", "aa", "aaa"
思路
方法一:直接暴力枚举,先枚举长度 O(n^3)
直接枚举回文的长度,根据不同长度来切分原字符串,判断每个小切分块是否是回文
方法二:中心扩散枚举,先枚举中心位置 O(n^2)
- 分奇偶型字符串情况来枚举,对于奇数型回文直接就是枚举中心位置,对于偶数型回文枚举的是中间偏左的位置,同样可以分成n类,所有加起来就是答案
代码
方法一:
class Solution {
public int countSubstrings(String s) {
int n = s.length();
int res = n;
for (int len = 2; len <= n; len ++ ) {
for (int i = 0; i + len - 1 < n; i ++ ) {
String t = s.substring(i, i + len);
if (check(t)) {
res ++;
}
}
}
return res;
}
public boolean check(String s) {
int i = 0, j = s.length() - 1;
while (i < j) {
if (s.charAt(i) != s.charAt(j)) {
return false;
}
i ++;
j --;
}
return true;
}
}
方法二:
class Solution {
public int countSubstrings(String s) {
int n = s.length();
int res = 0;
//枚举中心位置
for (int k = 0; k < n; k ++ ) {
//对于奇数型回文串
for (int i = k, j = k; i >= 0 && j < n; i --, j ++ ) {
if (s.charAt(i) == s.charAt(j)) {
res ++;
} else break;
}
//对于偶数型回文串
for (int i = k, j = k + 1; i >= 0 && j < n; i --, j ++ ) {
if (s.charAt(i) == s.charAt(j)) {
res ++;
} else break;
}
}
return res;
}
}