LeetCode 28. 找出字符串中第一个匹配项的下标

207 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第4天,点击查看活动详情

1.描述

28. 找出字符串中第一个匹配项的下标 - 力扣(LeetCode)

实现 strStr() 函数。

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

 

说明:

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

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

 

示例 1:

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

示例 2:

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

示例 3:

输入:haystack = "", needle = ""
输出:0

提示:

  • 1 <= haystack.length, needle.length <= 10^4
  • haystack 和 needle 仅由小写英文字符组成

2.分析

尽管这道题可以使用系统提供的函数进行求解,但是一种更好的实现方式是使用KMP算法。KMP算法的大致思想是,匹配不上以后,不需要从头开始匹配,因为有一些字符串肯定是不能匹配的,因此可以通过在匹配过程中进行记录从而减少匹配次数。

3.AC代码

class Solution:
    def strStr(self, haystack: str, needle: str) -> int:
        if needle == "":
            return 0

        def c():
            a = [0]
            for i in range(1, len(needle)):
                j = a[i - 1]
                while j != 0 and needle[i] != needle[j]:
                    j = a[j - 1]
                a.append(j + 1 if needle[i] == needle[j] else j)
            return a

        a = c()

        def kmp():
            j = 0
            for i in range(len(haystack)):
                while j != 0 and needle[j] != haystack[i]:
                    j = a[j - 1]
                if needle[j] == haystack[i]:
                    j += 1
                if j == len(needle):
                    return i - len(needle) + 1
            return -1

        return kmp()

4.总结

这道题实际上暴力解法也可以,并且非常简单清晰。

如果字符串needle为空,直接返回0。
若needle不为空,则使用for循环看在haystack中有没有needle字符串,使用substring方法即可,第一个数字为起始索引位置,第二个数字为结束索引位置,左闭右开。
若都没有即是没找到,则返回-1。