前缀和(一道技巧性巨强的题目)

今天又刷了一道巨棒巨棒的题目

请看题


题目很啰嗦,其实就是要我们求出给定字符串中固定连续字串的个数。连续字串例如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;
    }
};


我觉得这个题技巧性还是特别特别强的,值得反复品味。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值