[Leetcode][python]Implement strStr()/KMP算法

题目大意

字符串匹配

解题思路

两种思路:
1. 直接一个个匹配过去(遍历)
2. KMP算法:参考
http://www.ruanyifeng.com/blog/2013/05/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm.html
http://blog.csdn.net/coder_orz/article/details/51708389

代码

遍历

class Solution(object):
    def strStr(self, haystack, needle):
        """
        :type haystack: str
        :type needle: str
        :rtype: int
        """
        length = len(needle)
        for i in range(len(haystack) - len(needle) + 1):
            if haystack[i:i+len(needle)] == needle:
                return i
        return -1

KMP

最后两个测试集超时,将就了,KMP算法的实现还是很重要的。

class Solution:
    def strStr(self, haystack, needle):
        """
        :type haystack: str
        :type needle: str
        :rtype: int
        """
        if not haystack:
            if needle:
                return -1
            else:
                return 0
        if not needle:
            return 0
        return self.kmp_match(haystack, needle)

    #KMP
    def kmp_match(self, s, p):  
        m = len(s)
        n = len(p)  
        cur = 0  # 起始指针cur  
        table = self.partial_table(p)  
        # print(table)
        while cur <= m-n: # 长度不够就终止  
            # print("新一轮匹配,开始位置", cur)
            for i in range(n):  # 一次匹配长度  
                if s[i+cur] != p[i]:  
                    # print(s[i+cur], p[i], '不匹配。查表位置:', i, i - table[i-1])
                    cur += max(i - table[i-1], 1) # 有了部分匹配表,我们不只是单纯的1位1位往右移,可以一次移动多位  
                    break  
            else:
                return cur 
        return -1  

    #部分匹配表  
    def partial_table(self, p):  
        '''''partial_table("ABCDABD") -> [0, 0, 0, 0, 1, 2, 0]'''  
        prefix = set()  
        table = [0]  
        for i in range(1, len(p)):  # 从1开始进行前后缀比较  
            prefix.add(p[:i])  # 前缀每次累加就行
            postfix = set()
            for j in range(1, i+1):  # i+1 因为i需要包括
                postfix.add(p[j:i+1]) 
            # print(prefix, postfix)
            # print(prefix&postfix, len(prefix&postfix))
            # table.append(len((sorted((prefix&postfix),key = len)or {''}).pop()))
            if prefix&postfix:
                table.append(max(map(len,prefix&postfix)))
            else:
                table.append(0)
        return table  

总结

题目标签是双指针,我觉得基本思路就是找到第一个字母后逐一匹配后面的,其实KMP也是这样的,只不过用了一个表直接利用之前的匹配信息跳过一些不必要的匹配,有空仔细研究下。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值