zoukankan      html  css  js  c++  java
  • [Leetcode]28. Implement strStr()

    这是Leetcode第28题,实现strStr()函数,即在haystack中找出needle第一次出现的位置,如果不存在,那么就返回-1。
    又是一个经典的算法:KMP算法,这是和之前的Manacher算法并列的两大经典算法。KMP算法本质是通过next 数组实现当模式串中的某个字符跟文本串中的某个字符匹配失配时,模式串下一步应该跳到的位置。
    具体代码如下:

    class Solution:
        def strStr(self, haystack, needle):
            """
            :type haystack: str
            :type needle: str
            :rtype: int
            """
            return self.kmp(haystack,needle)
    
        def kmp(self,s,p):
            s_len = len(s)
            p_len = len(p)
            i,j = 0,0
            next = self.get_next(p)
            while(i<s_len and j<p_len):
                if(j == -1 or s[i]==p[j]):
                    i+=1
                    j+=1
                else:
                    j = next[j]
            if j==p_len:return i-j
            else:return -1
    
        def get_next(self,p):
            next = [-1 for i in range(len(p))]
            p_len = len(p)
            k,j = -1,0
            while(j<p_len-1):
                if k==-1 or p[j]==p[k]:
                    j+=1
                    k+=1
                    if p[j]!=p[k]:
                        next[j] = k
                    else:next[j] = next[k]
                else:k=next[k]
            return next
    

    扩展
    【Leetcode】214. Shortest Palindrome
    给一个字符串(s),在前面添加字符,求能得到的最短回文长度。
    实际上是求必须包括第一个字符串的情况下,最长回文子串是多长,后面的逆序添加即可。可求 s+'#'+s[::-1] 的最长前缀后缀,其最大长度的相同前缀和后缀就是前缀的最大回文长度。这就是朴素的KMP算法中next数组得含义。之所以是朴素的,是因为上面优化后的next数组引入了出p[next[j]] = p[j] 的情况,则把 next[j] 的值再次递归。,改变了原有的含义。
    具体代码如下:

    class Solution:
        def shortestPalindrome(self, s: str) -> str:
            """
            :type s: str
            :rtype: str
            """
            if not s:return s
            tmp = s + '#' + s[::-1] + '*'
            next = self.get_next(tmp)
            return s[next[-1]:][::-1] + s
    
        def get_next(self,p):
            len_p = len(p)
            next = [-1 for i in range(len_p)]
            j,k = 0,-1
            while j<len_p-1:
                if p[j] == p[k] or k==-1:
                    j+=1
                    k+=1
                    next[j] = k
                else:
                    k = next[k]
            return next
    

    另外,是否发现KMP的扩展与Manacher算法的扩展十分相似呢?是的,如果在字符串后面添加字符使其成为最短回文串,也可以采用KMP算法的思想,求包括最后一个字符串的情况下,最长回文子串。

    参考:
    从头到尾彻底理解KMP

  • 相关阅读:
    VS使用技巧
    写的一个简单定时器(非独立线程)
    C/C++技巧
    【转载】R6034错误,C Runtime Error
    C/C++面试题(一)
    常用的coco2d-x游戏开发工具(转)
    AndroidJNI 调用JAVA(转)
    Android SDK +Eclipse+ADT+CDT+NDK 开发环境在windows 7下的搭建
    简单的字符串压缩--C代码
    SQLite: sqlite_master(转)
  • 原文地址:https://www.cnblogs.com/hellojamest/p/11581290.html
Copyright © 2011-2022 走看看