今天又刷了一道巨棒巨棒的题目
请看题
题目很啰嗦,其实就是要我们求出给定字符串中固定连续字串的个数。连续字串例如abc或者xyzabc都属于连续字串。如果我们用暴力解法的话,那时间复杂度为n^2肯定是不通过的
举个例子
比如连续字符串:abcd
连续子串长度为4的个数:1
连续子串长度为3的个数:2
连续子串长度为2的个数:3
连续子串长度为1的个数:4
所以字串个数为1+2+3+4。根据这个规律我们可以发现,我们只需要利用滑动窗口就可以算出一个随机字符串的所有的连续字串的个数了。
另外一个问题又来了。就是去重。例如字符串:abcdcxyzabcd中可分解成abcd和c和xyzabcd三个连续子串。c是abcd的字串,所以属于重复。而xyzabcd和abcd部分重叠,这该怎么算呢?
我们假设f(c, len)表示以字符c结尾长度为len的连续子串的个数
我们可以发现xyzabcd就是f(d, 7),abcd是f(d, 4),xyzabcd比abcd多的连续字串个数为:f(d, 7)-f(d, 4) = f(z, 3) + (7-3)。
而因为滑动窗口自左扩散到右。xyz和abcd肯定早就是找到计算在内的,所以我们找到xyzabcd的时候,实际上只增加了7-3个连续子串。
代码如下
class Solution {
public:
int findSubstringInWraproundString(string p) {
int n = p.size();
if(n==1){
return 1;
}
int l = 1, ans = 1;
vector<int>mp(26, 0);
mp[p[0]-'a']=1;
for(int i=1; i<n; i++){
if(p[i]-'a' == (p[i-1]+1-'a')%26){
l++;
}else{
l = 1;
}
if(l>mp[p[i]-'a']){
ans+=(l-mp[p[i]-'a']);
mp[p[i]-'a'] = l;
}
}
return ans;
}
};
我觉得这个题技巧性还是特别特别强的,值得反复品味。