【训练营】Day09 字符串

Day09 字符串

1. 💥实现 strStr()

● 28. 实现 strStr()

KMP算法经典题:解决字符串匹配的问题

暴力解决时间复杂度为O(m*n):文本串长度和模式串长度

最长相等前后缀:前缀:只包含字母的前缀;后缀:只包含字母的前缀

next数组:匹配过程中遇到冲突时,指针应该回退到的位置

找到的不匹配的位置, 那么此时我们要看它的前一个字符的前缀表的数值是多少。

匹配的过程是O(n),之前还要单独生成next数组,时间复杂度是O(m)。所以整个KMP算法的时间复杂度是O(n+m)的

class Solution:
    def strStr(self, haystack: str, needle: str) -> int:
        def getNext(next, s):
            j = -1
            next[0] = j
            for i in range(1, len(s)):
                while j>=0 and s[i] != s[j+1]:
                    j = next[j]
                if s[i] == s[j+1]:
                    j+=1
                next[i] = j
        # 匹配
        if not needle: return 0
        next = [0] * len(needle)
        getNext(next, needle)
        j = -1
        for i in range(len(haystack)):
            while j >= 0 and haystack[i] != needle[j+1]:
                j = next[j]
            if haystack[i] == needle[j+1]:
                j +=1
            if j == len(needle) -1:
                return i-len(needle) +1
        return -1

2. 重复的子字符串

● 459.重复的子字符串

①移动匹配

如果字符串s由重复组合组成那么2s中间一定能找到s

class Solution:
    def repeatedSubstringPattern(self, s: str) -> bool:
        n = len(s)
        if n <= 1:
            return False
        ss = s[1:] + s[:-1] 
        print(ss.find(s))              
        return ss.find(s) != -1

②KMP

class Solution:
    def repeatedSubstringPattern(self, s: str) -> bool:     

        if len(s) == 0: return False
        next = [0] * len(s)
        self.getNext(next,s)
        if next[-1] != -1 and len(s) % (len(s)-(next[-1]+1)) == 0:
            return True
        return False
    def getNext(self, next, s):
        j = -1
        next[0] = j
        for i in range(1,len(s)):
            while j>=0 and s[j+1] != s[i]:
                j = next[j]
            if s[j+1] == s[i]:
                j+=1
            next[i] = j
        return next

3. 字符串总结

  • 字符串匹配:KMP算法,二刷了还是有点不太懂,实在不行就背吧,背着背着就会了
  • 双指针法
  • 库函数erase来移除元素,这其实是O(n^2)的操作
  • kmp中:其中主要理解j=next[x]这一步最为关键!

4. 双指针回顾

  • 字符串问题:定义两个指针(也可以说是索引下标),一个从字符串前面,一个从字符串后面,两个指针同时向中间移动,并交换元素。,时间复杂度是O(n)。
  • 链表问题:使用快慢指针(双指针法),分别定义 fast 和 slow指针,从头结点出发,fast指针每次移动两个节点,slow指针每次移动一个节点,如果 fast 和 slow指针在途中相遇 ,说明这个链表有环
  • n数之和问题:通过前后两个指针不算向中间逼近,在一个for循环下完成两个for循环的工作。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值