题目描述
给你一个字符串s,请你统计并返回这个字符串中回文子串的数目。
具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被视作不同的子串。
示例 1:
输入:s = "abc"
输出:3
解释:三个回文子串:"a", "b", "c"
示例 2:
输入:s = "aaa"
输出:6
解释:6个回文子串:"a", "a", "a", "aa", "aa", "aaa"
题解
C++
动态规划,时间复杂度 O ( n 2 ) O(n^2) O(n2),空间复杂度 O ( n 2 ) O(n^2) O(n2):
class Solution {
public:
int countSubstrings(string s) {
vector<vector<bool>> records(s.length(), vector<bool>(s.length(), false)); // 用于记录s[i]到s[j]之间的子串是否为回文串
int count = 0; // 用于统计总数
for (int i = s.length() - 1; i >= 0; --i) {
for (int j = i; j < s.length(); ++j) {
if (s[i] == s[j]) {
if (j - i <= 1) {
// s[i]与s[j]相同或相邻
records[i][j] = true;
++count;
} else {
if (records[i + 1][j - 1]) {
//s[i + 1]到s[j - 1]的子串为回文串
records[i][j] = true;
++count;
}
}
}
}
}
return count;
}
};
通过双指针从前向后依次统计,时间复杂度 O ( n 2 ) O(n^2) O(n2),空间复杂度 O ( 1 ) O(1) O(1):
class Solution {
public:
int countSubstrings(string s) {
int count = 0;
for (int i = 0; i < s.length(); ++i) {
count += symmetricallyGrow(s, i, i, s.length()); // 以s[i]为中心进行统计
count += symmetricallyGrow(s, i, i + 1, s.length()); // 以s[i]-s[i+1]为中心进行统计
}
return count;
}
/**
* 以s[start]-s[end]为中心向两边对称发送统计回文串数目
* @param s 待统计字符串
* @param start 初始头位置
* @param end 初始尾位置
* @param max_len 字符串长度
* @return
*/
int symmetricallyGrow(const string& s, int start, int end, int max_len) {
int count = 0;
while (start >= 0 && end < max_len && s[start] == s[end]) {
--start;
++end;
++count;
}
return count;
}
};
Python
通过双指针从前向后依次统计,时间复杂度 O ( n 2 ) O(n^2) O(n2),空间复杂度 O ( 1 ) O(1) O(1):
class Solution:
def countSubstrings(self, s: str) -> int:
count = 0
for i in range(len(s)):
count += self.symmetricallyGrow(s, i, i, len(s)) # 以s[i]为中心进行统计
count += self.symmetricallyGrow(s, i, i + 1, len(s)) # 以s[i]-s[i+1]为中心进行统计
return count
def symmetricallyGrow(self, s: str, start: int, end: int, max_len: int) -> int:
count = 0
while start >= 0 and end < max_len and s[start] == s[end]:
start -= 1
end += 1
count += 1
return count