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
    评论
用c语言实现寻找获胜字符串问题 :用c语言实现寻找获胜字符串问题 M 个银行职员玩一个游戏,每人拿着一个长度为 3 的数字串(注意:长度小于三个 数字的,左边补 0.例如, 5 为 005)。每个银行职员手中的数字串,都制定了一定的奖励 或惩罚分数。作为一个玩家,假定你从集合{0,1,2,3,4,5,6,7,8,9}中选择 n 个数字组 成一个数字串。如果你的数字串中有银行职员的数字串,那么你会因此加分或减分。例 如,有两个银行职员,一个职员给数字串 356 奖励 20 分,另一个职员给数字串 678 惩 罚 10 分。你的数字串是 035674,因为你的数字串中有 356 和 674,所以得分是 20-10=10 分。得分最高的玩家赢得这局游戏。假如不止一个玩家获得最高分,那么数字串值最小 的玩家获胜。 现在,假如哈利波特挥舞他的魔杖,弄清楚所有银行职员保密的字符串及相应的分 值,即使有赫敏在他身边,要想获胜也不是一件容易的事情。所以他向你求助;给定字 符串长度,请编写程序,帮助他找到获胜的字符串。 输入: 输入有多组测试数据。 对每组测试数据,第一行有两个整数 m 和 n(1<=n<=1000),其中 m 是银行职员人数, n 是玩家的字符串长度。 接下来有 m 行,每行是一个银行职员的字符串,及相应的分值。 假设所有银行职员的字符串都是互不相同的。 输出: 对每组测试数据,输出一行,内容是找到的获胜字符串。数字之间没有空格。 输入样例 2 5 356 20 674 -10 输出样例: 00356
06-11

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值