字符串哈希

1. LC 3292 形成目标字符串需要的最少字符串数Ⅱ

这题在3291的基础上开大数据量了。

3291我是比较标准的dp+字典树优化匹配。先把所有word扔到字典树里面,定义dp[i]表示到target[i]需要的最少次数。对于每个i进行target子串的最长前缀匹配,随后向后刷表。

其实,“target子串的最长前缀匹配”,其实就是主站45题跳跃游戏Ⅱ的贪心。如果你在抵达当前跳的途中,遇到右端点更远的索引,即可更新当前跳为该跳,次数即为更新次数:

45. 跳跃游戏 II - 力扣(LeetCode)

不过字典树的O(nk)显然是超时的,n是words数组长度,k是words数组元素长度总和。

这里看了灵神题解后,学到了单模(这里单模因为数据量小,不会哈希碰撞)字符串哈希的操作。首先对于任意索引i,如果target[i:j]有匹配前缀,那么target[i:j-k](其中j-k≥i)一定有匹配;若target[i:j]没有匹配,那么target[i:j+k](其中k≥0)一定没有匹配。

因此可以把所有前缀的哈希置入一个set的列表sets,sets[j]表示前缀长度为j的字符串的哈希值的集合。二分检查最长的匹配对应的是哪个set即可找到最长匹配。然后套跳跃游戏的贪心即可:

from typing import List
from random import randint

class Solution:
    def minValidStrings(self, words: List[str], target: str) -> int:
        n = len(target)

        MOD = 1_070_777_777
        BASE = randint(8*10**8,9*10**8)
        pow_base = [1] + [0 for _ in range(n)]
        pre_hash  = [0 for _ in range(n+1)]
        
        for i,c in enumerate(target):
            pow_base[i+1] = pow_base[i]*BASE%MOD
            pre_hash[i+1] = (pre_hash[i]*BASE+ord(c))%MOD
        
        max_len = max(map(len,words))
        sets = [set() for _ in range(max_len+1)]
        for w in words:
            hash = 0
            for i,c in enumerate(w):
                hash = (hash*BASE+ord(c))%MOD
                sets[i+1].add(hash)
        
        def sub_hash(l:int,r:int)->int:
            return (pre_hash[r]-pre_hash[l]*pow_base[r-l])%MOD
        
        # 45
        ans,cur_r,nxt_r = 0,0,0
        for i in range(n):
            
            def len_bs(start:int)->int:
                l,r,ans = 0,min(n-start,max_len)+1,0
                while l<r:
                    mid = (l+r)//2
                    
                    check = sub_hash(i,i+mid) in sets[mid]
                    if check:
                        ans = mid
                        l = mid+1
                    else:
                        r = mid
                
                return ans
            
            nxt_r = max(nxt_r,i+len_bs(i))
            if i==cur_r:
                if i==nxt_r:
                    return -1
                cur_r = nxt_r
                ans += 1
        
        return ans     

复杂度:O(nlogn+k)。我没用过bisect,也懒得学怎么用,直接手写了个二分。

内容概要:集成测试是确保软件质量的关键环节,它在单元测试基础上验证模块间的交互和协作。文章详细介绍了集成测试的目的、重要性、流程步骤、策略与方法以及常见问题的解决办法。集成测试不仅验证模块接口的正确性,还确保系统的整体功能和性能符合预期。文章通过一个电商系统的实际案例,展示了集成测试在发现和解决问题中的具体应用。最后,展望了集成测试未来的发展趋势,如自动化测试、云计算、大数据和人工智能技术的应用。 适合人群:软件开发人员、测试工程师、项目经理及相关技术人员。 使用场景及目标:①了解集成测试在整个软件开发生命周期中的作用和重要性;②掌握集成测试的详细流程,包括测试计划制定、环境搭建、用例设计、执行与记录、缺陷管理和回归测试、测试总结与报告;③学习集成测试的不同策略(自顶向下、自底向上、混合策略)和方法(黑盒测试、白盒测试、模拟测试),并理解其适用场景;④掌握常见问题(接口不匹配、数据传递错误、性能瓶颈)的解决办法。 其他说明:本文不仅提供了集成测试的理论知识,还结合实际案例进行详细讲解,帮助读者更好地理解和应用集成测试技术。未来集成测试将受益于自动化测试、云计算、大数据和人工智能技术的发展,测试人员应不断学习新技术,优化测试流程,提高软件质量和效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值