zoukankan      html  css  js  c++  java
  • LeetCode 28. 实现 strStr()

    题目:


    实现 strStr() 函数。

    给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在,则返回 -1。

    示例 1:

    输入: haystack = "hello", needle = "ll"
    输出: 2
    

    示例 2:

    输入: haystack = "aaaaa", needle = "bba"
    输出: -1
    

    说明:

    当 needle 是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。

    对于本题而言,当 needle 是空字符串时我们应当返回 0 。这与C语言的 strstr() 以及 Java的 indexOf() 定义相符。


    思路:

    从stack那边找到匹配的第一个字符为止,找到继续,找不到跳过继续匹配,当余下长度小于needle 长度则认为找不到返回-1.

    方法一:

    忍不住想用find..呵呵呵.

    class Solution(object):
        def strStr(self, haystack, needle):
            """
            :type haystack: str
            :type needle: str
            :rtype: int
            """
            len_s = len(haystack)
            len_n = len(needle)
            if len_n == 0:
                return 0
            return haystack.find(needle)
    

    方法二:

    依次查找,以needle的长度去遍历,找到就返回位置,找不到返回-1,因为是遍历所有长度,所以可以加一个检查,当stack的i位置不等于needle的首字符就跳过,减少时间。

    class Solution(object):
        def strStr(self, haystack, needle):
            """
            :type haystack: str
            :type needle: str
            :rtype: int
            """
            len_s = len(haystack)
            len_n = len(needle)
            if len_n == 0:
                return 0
            for i in xrange(len_s-len_n+1):
                if haystack[i] != needle[0]:
                    continue
                while (haystack[i:i+len_n] == needle):
                    return i
            return -1
    

    或者是双指针移动归位计算,匹配到就返回,匹配不到就依次进一位。

    class Solution(object):
        def strStr(self, haystack, needle):
            """
            :type haystack: str
            :type needle: str
            :rtype: int
            """
            len_s, len_n = len(haystack), len(needle)
            if L == 0:
                return 0
            start = 0
            while start < len_s - len_n + 1:
                curr_len = 0
                while curr_len < len_n and haystack[start] == needle[curr_len]:
                    start += 1
                    curr_len += 1
                if curr_len == len_n:
                    return start - len_n
                start = start - curr_len + 1
            return -1
    

    方法三:

    KMP算法,研究了好几个博客,终于圆上为什么可以直接移动k....这个解释了。

    不过我是说不出来,大概就是知道它为什么要这样写。

    记录下KMP算法大佬们的心得。

    详解KMP算法

    KMP算法最浅显理解——一看就明白

    KMP算法next数组的一种理解思路

    [KMP算法详解-彻底清楚了(转载+部分原创)]

    下面转自提解大大yi-wen-statistics 本题的KMP 算法解释。

    方法二中可能存在不少的重复性对比,例如'ABCDFABCDE'与'ABCDE'进行匹配,依照BF算法,需要按顺序逐个比较但实际上第一轮对比过程中发现'E'与'F'不同时可以直接将待匹配字符串向后挪移四格,这样就大大缩短了匹配时间,而KMP的核心思想便在于此——永不回溯。

    但还存在一个问题,如果待匹配字符串中出现相同的模式,例如'BBCBBB',且恰好字符库中也存在这样的模式(也可以认为是部分匹配),这时就无法按照上面的方式进行移动了,因此我们还需要一个跳跃数组来辅助我们的对比,我们每次遇到不相同的字符后,就将指针跳跃到后缀字符中部分匹配的位置,这样一来就能避免漏判的情况。

    class Solution(object):
        def strStr(self, haystack, needle):
            """
            :type haystack: str
            :type needle: str
            :rtype: int
            """
            n = len(needle)
            m = len(haystack)
            if n == 0: return 0
            j = 0
            pnext = self.getnext(needle)
            for i in range(m):
                while j > 0 and needle[j] != haystack[i]:
                    j = pnext[j]
                if needle[j] == haystack[i]:
                    j += 1
                    if j == n:
                        return i-n+1
            return -1
            
        def getnext(self, s):
            n = len(s)
            pnext = [0, 0] # 多一个前导0是为了方便后续指针跳跃,避免死循环
            j = 0
            for i in range(1, n):
                while j > 0 and s[i] != s[j]:
                    j = pnext[j] # 指针跳跃
                if s[j] == s[i]:
                    j += 1
                pnext.append(j)
            return pnext
    
    Knowledge, like candlelight, can illuminate a person and countless people.
  • 相关阅读:
    MySql常用命令
    PHP截断函数mb_substr()
    explode() 字符串转换数组
    php取得当前时间函数
    Apache与Nginx的比较
    thinkphp5.0环境变量配置
    thinkphp5.0配置作用域
    thinkphp5.0动态配置
    Mac 下查看 Android Studio 的 SHA1的方法
    Mac 下 gradle 路径
  • 原文地址:https://www.cnblogs.com/xiaoqiangink/p/14334938.html
Copyright © 2011-2022 走看看