【LeetCode】28. 找出字符串中第一个匹配项的下标 【字符串单模匹配:KMP算法】

2023-12-09 06:28

本文主要是介绍【LeetCode】28. 找出字符串中第一个匹配项的下标 【字符串单模匹配:KMP算法】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目链接

在这里插入图片描述

在这里插入图片描述

Python3

直觉解法

class Solution:def strStr(self, haystack: str, needle: str) -> int:pn, ph = 0, 0n = len(needle) h = len(haystack)while ph < h:if haystack[ph] == needle[pn]:if pn == n-1: # 1234   123return ph - len(needle) + 1else: pn += 1ph += 1else: ## 1234  122ph = ph - pn + 1pn = 0return -1

方法一: 暴力解法 ⟮ O ( n × m ) 、 O ( 1 ) ⟯ \lgroup O(n\times m)、O(1) \rgroup O(n×m)O(1)⟯

class Solution:def strStr(self, haystack: str, needle: str) -> int:for i in range(0, len(haystack)-len(needle)+1):if haystack[i:i+len(needle)] == needle:return i return -1

在这里插入图片描述

⭐ 方法二:Knuth-Morris-Pratt 算法 [KMP算法] ⟮ O ( m + n ) 、 O ( m ) ⟯ \lgroup O(m+n)、O(m) \rgroup O(m+n)O(m)⟯ 【空间换时间】

在这里插入图片描述
在这里插入图片描述
从而实现 更快地 跳转

在这里插入图片描述
参考链接1
参考链接2: KMP字符串匹配算法2

官方解法链接

class Solution:def strStr(self, haystack: str, needle: str) -> int:h = len(haystack)n = len(needle)# 获取 needle 的前缀信息lis = [0] * n j = 0  # 前后  子串长度for i in range(1, n): # 需要前后比较, 1个字符无法比较,因此从 i=1 开始while j > 0 and needle[i] != needle[j]: j = lis[j-1] # 和之前 相等的长度一样if needle[i] == needle[j]:j += 1  lis[i] = j # 0  1 2 3 4 5 6# a  a b a a a b   needle# 0  1 0 1 2 2 3  前缀子串 后缀子串 相同的长度  若是 needle[j] 不匹配了,注意是 lis[j-1] 存储的才是 待比较的下一个 j# a  a c a a# 根据上述的 信息进行 匹配j = 0  # 遍历 needle 下标for i in range(0, h): # 遍历 haystack 下标while j > 0 and haystack[i] != needle[j]:  #               j = lis[j-1]  # 这里 根据 前后缀 信息  快速跳转  if haystack[i] == needle[j]:j += 1if j == n: # needle 已全部匹配 因为前面的if 成立,j多加了1 return i - n + 1return -1 

在这里插入图片描述
链接

class Solution:def strStr(self, haystack: str, needle: str) -> int:def get_next():for i in range(1, len(needle)):k =[i-1]while needle[i] != needle[k]:if k == 0:k -= 1break else:k =[k-1][i] = k+1n = len(needle)= [0] * n get_next()   # 生成 needle 的next 数组i = 0 j = 0 while i < len(haystack):if haystack[i] == needle[j]:i += 1j += 1elif j == 0:i += 1else:j =[j-1]if j >= n:return i - n return -1

C++

KMP 算法 ⟮ O ( h + n ) 、 O ( n ) ⟯ \lgroup O(h+n)、O(n) \rgroup O(h+n)O(n)⟯

class Solution {
public:int strStr(string haystack, string needle) {int h = haystack.size(), n = needle.size();vector<int> lis(n);for (int i = 1, j = 0; i < n; ++i){while (j > 0 && needle[i] != needle[j]){j = lis[j-1];}if (needle[i] == needle[j]){++j;}lis[i] = j;}for (int i = 0, j = 0; i < h; ++i){while (j > 0 && haystack[i] != needle[j]){j = lis[j-1];}if (haystack[i] == needle[j]){++j;}if (j == n){return i - n + 1;}}return -1;}
};

暴力解法

class Solution {
public:int strStr(string haystack, string needle) {int h = haystack.size(), n = needle.size();int j = 0, i = 0;while (i < h){if (haystack[i] == needle[j]){if (j == n-1){return i - n + 1;}else{++j;++i;}}else{j = 0;i = i - j + 1;}}return -1;}
};

这篇关于【LeetCode】28. 找出字符串中第一个匹配项的下标 【字符串单模匹配:KMP算法】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/472795

相关文章

C++使用栈实现括号匹配的代码详解

《C++使用栈实现括号匹配的代码详解》在编程中,括号匹配是一个常见问题,尤其是在处理数学表达式、编译器解析等任务时,栈是一种非常适合处理此类问题的数据结构,能够精确地管理括号的匹配问题,本文将通过C+... 目录引言问题描述代码讲解代码解析栈的状态表示测试总结引言在编程中,括号匹配是一个常见问题,尤其是在

Java中String字符串使用避坑指南

《Java中String字符串使用避坑指南》Java中的String字符串是我们日常编程中用得最多的类之一,看似简单的String使用,却隐藏着不少“坑”,如果不注意,可能会导致性能问题、意外的错误容... 目录8个避坑点如下:1. 字符串的不可变性:每次修改都创建新对象2. 使用 == 比较字符串,陷阱满

IDEA编译报错“java: 常量字符串过长”的原因及解决方法

《IDEA编译报错“java:常量字符串过长”的原因及解决方法》今天在开发过程中,由于尝试将一个文件的Base64字符串设置为常量,结果导致IDEA编译的时候出现了如下报错java:常量字符串过长,... 目录一、问题描述二、问题原因2.1 理论角度2.2 源码角度三、解决方案解决方案①:StringBui

关于Gateway路由匹配规则解读

《关于Gateway路由匹配规则解读》本文详细介绍了SpringCloudGateway的路由匹配规则,包括基本概念、常用属性、实际应用以及注意事项,路由匹配规则决定了请求如何被转发到目标服务,是Ga... 目录Gateway路由匹配规则一、基本概念二、常用属性三、实际应用四、注意事项总结Gateway路由

C#从XmlDocument提取完整字符串的方法

《C#从XmlDocument提取完整字符串的方法》文章介绍了两种生成格式化XML字符串的方法,方法一使用`XmlDocument`的`OuterXml`属性,但输出的XML字符串不带格式,可读性差,... 方法1:通过XMLDocument的OuterXml属性,见XmlDocument类该方法获得的xm

JSON字符串转成java的Map对象详细步骤

《JSON字符串转成java的Map对象详细步骤》:本文主要介绍如何将JSON字符串转换为Java对象的步骤,包括定义Element类、使用Jackson库解析JSON和添加依赖,文中通过代码介绍... 目录步骤 1: 定义 Element 类步骤 2: 使用 Jackson 库解析 jsON步骤 3: 添

Java 字符数组转字符串的常用方法

《Java字符数组转字符串的常用方法》文章总结了在Java中将字符数组转换为字符串的几种常用方法,包括使用String构造函数、String.valueOf()方法、StringBuilder以及A... 目录1. 使用String构造函数1.1 基本转换方法1.2 注意事项2. 使用String.valu

Python中的随机森林算法与实战

《Python中的随机森林算法与实战》本文详细介绍了随机森林算法,包括其原理、实现步骤、分类和回归案例,并讨论了其优点和缺点,通过面向对象编程实现了一个简单的随机森林模型,并应用于鸢尾花分类和波士顿房... 目录1、随机森林算法概述2、随机森林的原理3、实现步骤4、分类案例:使用随机森林预测鸢尾花品种4.1

python修改字符串值的三种方法

《python修改字符串值的三种方法》本文主要介绍了python修改字符串值的三种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学... 目录第一种方法:第二种方法:第三种方法:在python中,字符串对象是不可变类型,所以我们没办法直接

JAVA中整型数组、字符串数组、整型数和字符串 的创建与转换的方法

《JAVA中整型数组、字符串数组、整型数和字符串的创建与转换的方法》本文介绍了Java中字符串、字符数组和整型数组的创建方法,以及它们之间的转换方法,还详细讲解了字符串中的一些常用方法,如index... 目录一、字符串、字符数组和整型数组的创建1、字符串的创建方法1.1 通过引用字符数组来创建字符串1.2