647. 回文子串 - 力扣(LeetCode)
给你一个字符串 s
,请你统计并返回这个字符串中 回文子串 的数目。
回文字符串 是正着读和倒过来读一样的字符串。
子字符串 是字符串中的由连续字符组成的一个序列。
示例 1:
输入:s = "abc"
输出:3
解释:三个回文子串: "a", "b", "c"
示例 2:
输入:s = "aaa"
输出:6
解释:6个回文子串: "a", "a", "a", "aa", "aa", "aaa"
题解
暴力解决
枚举给定字符串中所有的子串 判断一个字符串是否是回文
——外层循环 子串起始位置 内层循环 子串结束位置 时间复杂度 o(n2)
——是否是回文 检测一个字符串是需要 逐一遍历每个字符 可以视作 原字符长度 n 的函数
——整个方案的 时间复杂度为 O(n3)
class Solution {
public:
// Function to count the number of palindromic substrings in the input
// string
int countSubstrings(const std::string& s) {
int n = s.size();
int count = 0;
// Generate substrings using two nested loops
for (int i = 0; i < n; ++i) {
for (int j = i; j < n; ++j) {
// Check if the current substring is a palindrome
if (isPalindrome(s, i, j)) {
++count;
}
}
}
return count;
}
// Function to check if a given string is a palindrome
bool isPalindrome(const std::string& str, int left, int right) {
while (left < right) {
if (str[left] != str[right]) {
return false;
}
++left;
--right;
}
return true;
}
};
中心扩展
枚举每一个可能是中心的字符 然后向两边扩展
分为两种情况:一种是奇数 中心为一个字符
另一种为偶数 中心为两个字符
class Solution {
public:
int countSubstrings(string s) {
int n = s.length();
int ans = 0;
for (int center = 0; center < n; center++) {
ans += expand(s, center, center) + expand(s, center, center + 1);
}
return ans;
}
private:
int expand(string s, int left, int right) {
int ans = 0;
while (left >= 0 && right < s.length() &&
s[left] == s[right]) {
ans++;
left--;
right++;
}
return ans;
}
};