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

题目描述:

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

题解:

class Solution:
    def strStr(self, haystack: str, needle: str) -> int:
        p, q = 0, 0
        n = len(needle)
        m = len(haystack)    
        while p < m and q < n:
            if needle[q] == haystack[p]:
                p += 1
                q += 1
            else:
                p = p - q + 1  # 回溯到上一个匹配的位置的下一个字符
                q = 0
        if q == n:
            return p - q
        else:
            return -1  

思路:

  1. 双指针: 使用两个指针 pq 分别表示在 haystackneedle 中当前比较的位置。

  2. 循环比较: 在循环中,比较 haystack[p]needle[q] 是否相等。如果相等,两个指针都向前移动;如果不相等,需要回溯到上一个匹配的位置的下一个字符,并将 q 重置为 0。

  3. 回溯: 回溯的位置是 p = p - q + 1,即将 p 移动到上一个匹配位置的下一个字符。

  4. 判断匹配: 在循环结束后,检查 q 是否等于 needle 的长度。如果相等,说明完全匹配,返回起始位置 p - q;否则,返回 -1 表示未找到匹配的子串。

KMP算法:

class Solution:
    def strStr(self, haystack: str, needle: str) -> int:
        if not needle:
            return 0  # 如果 needle 为空,返回 0
        def build_kmp_table(pattern):
            table = [0] * len(pattern)
            j = 0
            for i in range(1, len(pattern)):
                while j > 0 and pattern[i] != pattern[j]:
                    j = table[j - 1]
                if pattern[i] == pattern[j]:
                    j += 1
                table[i] = j
            return table
        m, n = len(haystack), len(needle)
        if m < n:
            return -1  # 如果 haystack 长度小于 needle 长度,直接返回 -1
        kmp_table = build_kmp_table(needle)
        i, j = 0, 0
        while i < m:
            if haystack[i] == needle[j]:
                i += 1
                j += 1
                if j == n:
                    return i - n  # 如果 j 等于 needle 长度,说明完全匹配,返回起始位置
            else:
                if j > 0:
                    j = kmp_table[j - 1]  # 根据部分匹配表进行回溯
                else:
                    i += 1
        return -1  # 没有找到匹配

思路:

1. 构建 KMP 表

build_kmp_table 函数用于构建部分匹配表(PMT)。PMT 用于优化模式串的匹配过程,避免不必要的字符比较。

  • 初始化数组 table,用于存储部分匹配表。
  • 使用两个指针 ij,从模式串的第二个字符开始遍历。
  • 在循环中,如果当前字符匹配,增加 ji。如果不匹配,根据部分匹配表进行回溯。
  • 最终,table[i] 存储了模式串中以第 i 个字符结尾的最长相等前缀和后缀的长度。

2. 使用 KMP 算法进行匹配

strStr 函数使用 KMP 算法在文本串中查找模式串的第一个匹配项。

  • 如果模式串为空,直接返回 0(空串在任何字符串的开头都是匹配的)。
  • 调用 build_kmp_table 构建部分匹配表。
  • 使用两个指针 ij 分别遍历文本串和模式串。
  • 在循环中,如果当前字符匹配,增加 ij。如果 j 等于模式串长度,说明完全匹配,返回起始位置 i - n
  • 如果当前字符不匹配,根据部分匹配表进行回溯。如果 j > 0,将 j 设置为部分匹配表的值;否则,增加 i
  • 如果循环结束后没有找到匹配,返回 -1。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值