难度:中等
给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标(下标从 0 开始)。如果 needle 不是 haystack 的一部分,则返回 -1 。
示例 1:
输入:haystack = "sadbutsad", needle = "sad"
输出:0
解释:"sad" 在下标 0 和 6 处匹配。
第一个匹配项的下标是 0 ,所以返回 0 。
示例 2:
输入:haystack = "leetcode", needle = "leeto"
输出:-1
解释:"leeto" 没有在 "leetcode" 中出现,所以返回 -1 。
思路:
记 haystackhaystackhaystack 为 TTT,needlepneedlepneedlep 为 ppp,对于给定文本串 TTT 与模式串 ppp,先对模式串 ppp 进行预处理。然后在匹配的过程中,当发现文本串 TTT 的某个字符与模式串 ppp 不匹配的时候,根据启发策略,能够直接尽可能地跳过一些无法匹配的情况,将模式串多向后滑动几位。
BMBMBM 算法具体步骤如下:
时间复杂度: O(n/m)O(n/m)O(n/m),最坏O(m∗n)O(m*n)O(m∗n)
空间复杂度: O(suffix)O(suffix)O(suffix),suffixsuffixsuffix 为后缀长度,小于模式串 ppp。
class Solution:def strStr(self, haystack: str, needle: str) -> int:def boyerMoore(T: str, p: str) -> int:n, m = len(T), len(p)bc_table = generateBadCharTable(p) # 生成坏字符位置表gs_list = generageGoodSuffixList(p) # 生成好后缀规则后移位数表i = 0while i <= n - m:j = m - 1while j > -1 and T[i + j] == p[j]:j -= 1if j < 0:return ibad_move = j - bc_table.get(T[i + j], -1)good_move = gs_list[j]i += max(bad_move, good_move)return -1# 生成坏字符位置表def generateBadCharTable(p: str):bc_table = dict()for i in range(len(p)):bc_table[p[i]] = i # 坏字符在模式串中最后一次出现的位置return bc_table# 生成好后缀规则后移位数表def generageGoodSuffixList(p: str):m = len(p)gs_list = [m for _ in range(m)]suffix = generageSuffixArray(p)j = 0for i in range(m - 1, -1, -1):if suffix[i] == i + 1:while j < m - 1 - i:if gs_list[j] == m:gs_list[j] = m - 1 - ij += 1for i in range(m - 1):gs_list[m - 1 - suffix[i]] = m - 1 - ireturn gs_listdef generageSuffixArray(p: str):m = len(p)suffix = [m for _ in range(m)]for i in range(m - 2, -1, -1):start = iwhile start >= 0 and p[start] == p[m - 1 - i + start]:start -= 1suffix[i] = i - startreturn suffixreturn boyerMoore(haystack, needle)
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/find-the-index-of-the-first-occurrence-in-a-string