代码随想录算法训练营第九天| LeetCode28. 实现 strStr() 、LeetCode459.重复的子字符串

前缀表

基础知识

前缀表:模式串除了最后一个字符的所有子串(但必须从第一个开始),以及他们对应的最长相等前后缀
后缀表:模式串除了第一个字符的所有子串(从后往前,从最后一个开始)
最长相等前后缀:在最前和最后完全相同的子串
开始匹配的位置就是前缀表最大数对应的字符串的索引位置。
next数组有三种方式,第一种是正常的状态,第一是整体右移动,左边第一位填充-1,第二种是所有内容-1
第一种方式时,如果发生了冲突,就找发生冲突的前一位next表中的索引位置,第二种方式则找冲突位置对应的索引即可,第三种是找到前一位再加一。
next数组的四个步骤,初始化,前后缀不相同,前后缀相同,next。
初始化:i 后缀末尾,j前缀末尾,因为要找的就是最大相等的前后缀,那么j初始化成0,next初始化为[0],因为第一个位置肯定是0,例如a,他没有与之相等的后缀,也不可能会有,那么next表第一位一定是0,之后 i 就从1开始,因为i=0的时候时没有后缀的!!,i最大应该是模式串的最右边。
找不相等:不相等的情况就应该是尾部不相同,那j就要开始回退查找,j应该回退的位置下标就是它前一位所对应的next数字,也要不停的回退,直到找到相等的,或者是j到了尽头为0了
找到相等:如果此时i和j对应的元素是相等的,那么就可以先进行j+1,因为j是索引,+1之后才是最大相等前后缀的长度。next[i]之后就应该等于j,next[i]=j的含义是,包括i位置的字符串中,最大相等的前后缀的长度。
关于i和j的位置,我的个人理解是,每次起始的时候,j所指向的位置表示着先前有没有相等的前后缀,j为0,那么就说明在上一个轮次中,没有找到相等的前后缀,那如果j不为0,那么我们就要从j的位置继续找相等的前后缀,起到一个叠加的效果

28. 实现 strStr()

题目描述: 28. 实现 strStr().

解法

不减1的前缀表
class Solution(object):
    def strStr(self, haystack, needle):

        def init_next(needle):
            j = 0
            nextL = [0]*len(needle)
            for i in range(1,len(needle)):
                while j>0 and needle[i] != needle[j]:
                    j = nextL[j-1]
                if needle[i] == needle[j]:
                    j = j + 1   # j会先到下一个进行对比的地方,+1之后也正好是最大的前后缀相同长度
                nextL[i] = j
            return nextL
        
        nextL = init_next(needle)
        j = 0
        if not needle:
            return 0
        for i in range(len(haystack)):
            while j > 0 and haystack[i] != needle[j]:
                j = nextL[j-1]
            if haystack[i] == needle[j]:
                j += 1
            if j == len(needle):
                return i - len(needle) + 1
        return -1

首先是构建模式串的前缀表,这个表是主串用来查询的。
建立好表格之后,就开始在主串进行遍历,一直进行匹配,如果匹配不到了,就找距离最近的能和当前串匹配的模式串的子串,实际上就是主串削减了前一部分的串,而模式串削减了后一部分的串,这个串和模式串的前一部分是重合的,那么在主串中就可以不用从模式串的开头查找了,因为主串中已经有一部分是和削减之前的模式串的后一部分相同,也与削减后的模式串的前一部分相同,那如果没有相同的部分,就要在主串中,从模式串的头开始查找与模式串对应的部分了。那最后如果在模式串中的指针没有走到最后,那就意味着模式串没能完整的遍历完,也就是没有完整匹配。就要返回-1,如果j此时超出子串的长度,那么i此时对应的已经是模式串的最后一位了,那第一个匹配好的模式串的开头索引就应该是 i - 模式串长度 + 1。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
第二十二天的算法训练营主要涵盖了Leetcode题目中的三道题目,分别是Leetcode 28 "Find the Index of the First Occurrence in a String",Leetcode 977 "有序数组的平方",和Leetcode 209 "长度最小的数组"。 首先是Leetcode 28题,题目要求在给定的字符串中找到第一个出现的字符的索引。思路是使用双指针来遍历字符串,一个指向字符串的开头,另一个指向字符串的结尾。通过比较两个指针所指向的字符是否相等来判断是否找到了第一个出现的字符。具体实现代码如下: ```python def findIndex(self, s: str) -> int: left = 0 right = len(s) - 1 while left <= right: if s[left == s[right]: return left left += 1 right -= 1 return -1 ``` 接下来是Leetcode 977题,题目要求对给定的有序数组中的元素进行平方,并按照非递减的顺序返回结果。这里由于数组已经是有序的,所以可以使用双指针的方法来解决问题。一个指针指向数组的开头,另一个指针指向数组的末尾。通过比较两个指针所指向的元素的绝对值的大小来确定哪个元素的平方应该放在结果数组的末尾。具体实现代码如下: ```python def sortedSquares(self, nums: List[int]) -> List[int]: left = 0 right = len(nums) - 1 ans = [] while left <= right: if abs(nums[left]) >= abs(nums[right]): ans.append(nums[left ** 2) left += 1 else: ans.append(nums[right ** 2) right -= 1 return ans[::-1] ``` 最后是Leetcode 209题,题目要求在给定的数组中找到长度最小的数组,

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值