找出字符串中第一个匹配项的下标
难度:中等
给你两个字符串 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 。
Sunday算法
思路:
对于给定文本串 s 与模式串 p,先对模式串 p 进行预处理。然后在匹配的过程中,当发现文本串 s 的某个字符与模式串 p 不匹配的时候,根据启发策略,能够尽可能的跳过一些无法匹配的情况,将模式串多向后滑动几位。算法详解点击此处查看。
时间复杂度: 最坏情况:
O
(
n
m
)
O(nm)
O(nm),平均情况:
O
(
n
)
O(n)
O(n)
空间复杂度:
O
(
s
)
O(s)
O(s)。为偏移表长度。
class Solution:
def strStr(self, haystack, needle):
haystack_length = len(haystack)
needle_length = len(needle)
return self.sunday(haystack, haystack_length, needle, needle_length)
def sunday(self, s, s_len, p, p_len):
bc_move_dict = self.badChatMove(p, p_len)
now = 0
# 如果匹配字符的位置到达两字符串长度的差值,则不可能存在匹配字串,则退出循环
while now <= s_len - p_len:
# 比对当前位置的子串是否和模式串匹配
if s[now: now+p_len] == p:
return now
# 如果以及到达两字符串长度的差值,那么这将是最后一个可能匹配到的子串
# 经过上面的比对没有匹配的话,直接返回-1
if now == s_len - p_len:
return -1
# 更新下标,如果模式串不包含匹配串后面的第一个字符,则移动 p_len+1 个位数
now += bc_move_dict.get(s[now+p_len], p_len+1)
return -1
# 坏字符移动数量计算
def badChatMove(self, p, p_len):
bc_move_dict = dict()
for i in range(p_len):
# 记录该字符在模式串中出现的最右位置到尾部的距离+1
bc_move_dict[p[i]] = p_len - i
return bc_move_dict
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/find-the-index-of-the-first-occurrence-in-a-string