中心扩展法
中心扩展法
在计算回文子串个数时,首先能想到的算法是枚举子串的起始和结束端点,然后检查该子串是否为回文子串,这种算法的时间复杂度为\(O(n^3)\),这个效率在主串较长的情况下,复杂度是很高的,因此基于回文子串的特性,存在一种更优的算法:中心扩展法
中心扩展法基于回文串的特殊性质,回文串是一个对称的字符串,因此从回文串中心开始左右遍历,遍历到的字符应该是相同的,基于这种性质,在查找回文子串时,直接枚举中心,然后向左向右遍历,这样就可查找到以对应点为中心的所有回文子串,但是回文子串的长度有奇数有偶数,这在枚举中心时造成了一定麻烦,对此,存在一种特殊的枚举方法(建议直接记住) :
for(int i = 0; i < n * 2 - 1; ++i) {
int l = i / 2;
int r = i / 2 + i % 2;
}
这样枚举得到的l, r恰好是(0,0),(0,1),(1,1),(1,2),(2,2)的格式,满足了奇偶中心的特点,由此中心扩展法就完成了。
647. 回文子串 - 力扣(LeetCode)
class Solution {
public:
int countSubstrings(string s) {
int cnt = 0, n = s.length();
for(int k = 0; k < n * 2 - 1; ++k) {
int l = k / 2;
int r = k / 2 + k % 2;
while(l >= 0 && r < n && s[l] == s[r]) {
l--;
r++;
cnt++;
}
}
return cnt;
}
};