LeetCode【0028】找出字符串中第一个匹配项的下标

本文目录

  • [1 中文题目](#1 中文题目)
  • [2 求解方法:KMP算法](#2 求解方法:KMP算法)
    • [2.1 方法思路](#2.1 方法思路)
    • [2.2 Python代码](#2.2 Python代码)
    • [2.3 复杂度分析](#2.3 复杂度分析)
  • [3 题目总结](#3 题目总结)

1 中文题目

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

示例:

python 复制代码
输入:haystack = "sadbutsad", needle = "sad"
输出:0
解释:"sad" 在下标 0 和 6 处匹配。
第一个匹配项的下标是 0 ,所以返回 0 。
python 复制代码
输入:haystack = "leetcode", needle = "leeto"
输出:-1
解释:"leeto" 没有在 "leetcode" 中出现,所以返回 -1 。

提示:

  • 1 ≤ h a y s t a c k . l e n g t h , n e e d l e . l e n g t h ≤ 1 0 4 1 \leq haystack.length, needle.length \leq 10^4 1≤haystack.length,needle.length≤104
  • haystackneedle 仅由小写英文字符组成

2 求解方法:KMP算法

2.1 方法思路

方法核心

使用KMP算法实现字符串匹配,通过next数组(部分匹配表)优化匹配过程。并且避免不必要的回溯,提高效率

实现步骤

(1)构建next数组:

  • 计算模式串的最长相同前后缀
  • 用于在不匹配时快速回退

(2)字符串匹配:

  • 遍历主串进行匹配
  • 利用next数组进行高效回退
  • 找到完全匹配时返回起始位置

方法示例

python 复制代码
输入:haystack = "hello", needle = "ll"

1. 构建next数组:
needle = "ll"
next = [0, 1]

2. 匹配过程:
"hello"
 j=0
 i=0  h!=l  j=0
 i=1  e!=l  j=0
 i=2  l=l   j=1
 i=3  l=l   j=2 (匹配成功)

返回值:2

2.2 Python代码

python 复制代码
class Solution:
    def strStr(self, haystack: str, needle: str) -> int:
        # 如果needle为空,返回0
        if not needle:
            return 0
        
        # 获取两个字符串的长度
        n, m = len(haystack), len(needle)
        
        # 构建next数组(部分匹配表)
        def get_next(pattern):
            # next[i]表示pattern[0:i]的最长相同前后缀长度
            next = [0] * m
            # j指向前缀末尾,i指向后缀末尾
            j = 0
            
            # 从第二个字符开始计算next数组
            for i in range(1, m):
                # 当前字符不匹配,需要回退
                while j > 0 and pattern[i] != pattern[j]:
                    j = next[j - 1]
                # 当前字符匹配,更新j
                if pattern[i] == pattern[j]:
                    j += 1
                # 记录当前位置的最长相同前后缀长度
                next[i] = j
                
            return next
        
        # 获取next数组
        next = get_next(needle)
        
        # j指向needle的匹配位置
        j = 0
        
        # 遍历haystack进行匹配
        for i in range(n):
            # 当前字符不匹配,根据next数组回退
            while j > 0 and haystack[i] != needle[j]:
                j = next[j - 1]
            # 当前字符匹配,移动j
            if haystack[i] == needle[j]:
                j += 1
            # 完全匹配,返回起始位置
            if j == m:
                return i - m + 1
        
        # 未找到匹配,返回-1
        return -1

2.3 复杂度分析

  • 时间复杂度:O(n + m),n是haystack长度,m是needle长度
    • 构建next数组需要O(m)
    • 匹配过程需要O(n)
  • 空间复杂度:O(m)
    • next数组占用O(m)空间
    • 其他变量占用O(1)空间

3 题目总结

题目难度:简单
数据结构:字符串
应用算法:KMP算法

相关推荐
黑客-雨8 分钟前
从零开始:如何用Python训练一个AI模型(超详细教程)非常详细收藏我这一篇就够了!
开发语言·人工智能·python·大模型·ai产品经理·大模型学习·大模型入门
半盏茶香14 分钟前
扬帆数据结构算法之雅舟航程,漫步C++幽谷——LeetCode刷题之移除链表元素、反转链表、找中间节点、合并有序链表、链表的回文结构
数据结构·c++·算法
孤独且没人爱的纸鹤22 分钟前
【机器学习】深入无监督学习分裂型层次聚类的原理、算法结构与数学基础全方位解读,深度揭示其如何在数据空间中构建层次化聚类结构
人工智能·python·深度学习·机器学习·支持向量机·ai·聚类
l1x1n025 分钟前
No.35 笔记 | Python学习之旅:基础语法与实践作业总结
笔记·python·学习
CodeJourney.34 分钟前
小型分布式发电项目优化设计方案
算法
带多刺的玫瑰1 小时前
Leecode刷题C语言之从栈中取出K个硬币的最大面积和
数据结构·算法·图论
是Dream呀1 小时前
Python从0到100(八十五):神经网络-使用迁移学习完成猫狗分类
python·神经网络·迁移学习
Cando学算法1 小时前
Codeforces Round 1000 (Div. 2)(前三题)
数据结构·c++·算法
薯条不要番茄酱1 小时前
【动态规划】落花人独立,微雨燕双飞 - 8. 01背包问题
算法·动态规划
小林熬夜学编程1 小时前
【Python】第三弹---编程基础进阶:掌握输入输出与运算符的全面指南
开发语言·python·算法