算法刷题打卡第38天:找出字符串中第一个匹配项的下标---Sunday算法

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

难度:中等
给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标(下标从 0 开始)。如果 needle 不是 haystack 的一部分,则返回 -1 。

示例 1:

输入:haystack = "sadbutsad", needle = "sad"
输出:0
解释:"sad" 在下标 06 处匹配。
第一个匹配项的下标是 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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夏秃然

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值