2223. 构造字符串的总得分和

题意分析

2223. 构造字符串的总得分和 - 力扣(LeetCode)

        这题就是一个求前后缀匹配的问题,这种类型有个通常的模板——Z函数,只要弄明白z函数就可以了。

算法思路

z函数实现:

  1. 我们维持一个数组Z(n),用来记录每个i的匹配长度
  2. 判断s[z[i]]==s[i+z[i]],如果相等就z[i]++;不等就不用做
  3. 考虑到在[i,i+z[i]-1]区间中,将区间标记维[l,r],只要落到这个区间中的i是不需要再额外算的(因为已经算过了,不需要重复算),我们可以将z[i-l]转移给z[i]
  4. 但是如果z[i-l]长度超过了小盒子的长度,则就要将r-i+1赋值给z[i],然后盒子外的暴力比较一番。
  5. 最后更新盒子,如果i+z[i]>r了,那么比较就到盒子外去了,这时要更新l=i,r=i+z[i]-1,因为i+z[i]那里没有匹配成功。

代码实现

class Solution {
public:
    long long sumScores(string s) {
        int n=s.length();
        vector<int> z(n,0);
        z[0]=n;
        long long ans=z[0];
        for(int i=1,l=0,r=0;i<n;i++){
            if(i<=r) z[i]=min(z[i-l],r-i+1);
            while(s[z[i]]==s[i+z[i]]) z[i]++;
            if(i+z[i]>r) l=i,r=i+z[i]-1;
            ans+=z[i];
        }
        return ans;
    }
};

解题总结

z函数是kmp的一种拓展,用来解决前后缀问题简直不要太方便。本质就是将比较过的部分跳过不进行比较,但大大降低了时间复杂度。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值