mirror of
https://github.com/youngyangyang04/leetcode-master.git
synced 2025-07-09 03:34:02 +08:00
更新 0028.实现strStr 排版格式修复
This commit is contained in:
@ -28,7 +28,7 @@
|
|||||||
对于本题而言,当 needle 是空字符串时我们应当返回 0 。这与C语言的 strstr() 以及 Java的 indexOf() 定义相符。
|
对于本题而言,当 needle 是空字符串时我们应当返回 0 。这与C语言的 strstr() 以及 Java的 indexOf() 定义相符。
|
||||||
|
|
||||||
|
|
||||||
# 思路
|
## 思路
|
||||||
|
|
||||||
本题是KMP 经典题目。
|
本题是KMP 经典题目。
|
||||||
|
|
||||||
@ -60,13 +60,13 @@ KMP的经典思想就是:**当出现字符串不匹配时,可以记录一部
|
|||||||
读完本篇可以顺便把leetcode上28.实现strStr()题目做了。
|
读完本篇可以顺便把leetcode上28.实现strStr()题目做了。
|
||||||
|
|
||||||
|
|
||||||
# 什么是KMP
|
### 什么是KMP
|
||||||
|
|
||||||
说到KMP,先说一下KMP这个名字是怎么来的,为什么叫做KMP呢。
|
说到KMP,先说一下KMP这个名字是怎么来的,为什么叫做KMP呢。
|
||||||
|
|
||||||
因为是由这三位学者发明的:Knuth,Morris和Pratt,所以取了三位学者名字的首字母。所以叫做KMP
|
因为是由这三位学者发明的:Knuth,Morris和Pratt,所以取了三位学者名字的首字母。所以叫做KMP
|
||||||
|
|
||||||
# KMP有什么用
|
### KMP有什么用
|
||||||
|
|
||||||
KMP主要应用在字符串匹配上。
|
KMP主要应用在字符串匹配上。
|
||||||
|
|
||||||
@ -84,7 +84,7 @@ KMP的主要思想是**当出现字符串不匹配时,可以知道一部分之
|
|||||||
|
|
||||||
下面Carl就带大家把KMP的精髓,next数组弄清楚。
|
下面Carl就带大家把KMP的精髓,next数组弄清楚。
|
||||||
|
|
||||||
# 什么是前缀表
|
### 什么是前缀表
|
||||||
|
|
||||||
写过KMP的同学,一定都写过next数组,那么这个next数组究竟是个啥呢?
|
写过KMP的同学,一定都写过next数组,那么这个next数组究竟是个啥呢?
|
||||||
|
|
||||||
@ -122,7 +122,7 @@ next数组就是一个前缀表(prefix table)。
|
|||||||
|
|
||||||
那么什么是前缀表:**记录下标i之前(包括i)的字符串中,有多大长度的相同前缀后缀。**
|
那么什么是前缀表:**记录下标i之前(包括i)的字符串中,有多大长度的相同前缀后缀。**
|
||||||
|
|
||||||
# 最长公共前后缀?
|
### 最长公共前后缀
|
||||||
|
|
||||||
文章中字符串的**前缀是指不包含最后一个字符的所有以第一个字符开头的连续子串**。
|
文章中字符串的**前缀是指不包含最后一个字符的所有以第一个字符开头的连续子串**。
|
||||||
|
|
||||||
@ -144,7 +144,7 @@ next数组就是一个前缀表(prefix table)。
|
|||||||
等等.....。
|
等等.....。
|
||||||
|
|
||||||
|
|
||||||
# 为什么一定要用前缀表
|
### 为什么一定要用前缀表
|
||||||
|
|
||||||
这就是前缀表,那为啥就能告诉我们 上次匹配的位置,并跳过去呢?
|
这就是前缀表,那为啥就能告诉我们 上次匹配的位置,并跳过去呢?
|
||||||
|
|
||||||
@ -163,7 +163,7 @@ next数组就是一个前缀表(prefix table)。
|
|||||||
|
|
||||||
**很多介绍KMP的文章或者视频并没有把为什么要用前缀表?这个问题说清楚,而是直接默认使用前缀表。**
|
**很多介绍KMP的文章或者视频并没有把为什么要用前缀表?这个问题说清楚,而是直接默认使用前缀表。**
|
||||||
|
|
||||||
# 如何计算前缀表
|
### 如何计算前缀表
|
||||||
|
|
||||||
接下来就要说一说怎么计算前缀表。
|
接下来就要说一说怎么计算前缀表。
|
||||||
|
|
||||||
@ -205,7 +205,7 @@ next数组就是一个前缀表(prefix table)。
|
|||||||
|
|
||||||
最后就在文本串中找到了和模式串匹配的子串了。
|
最后就在文本串中找到了和模式串匹配的子串了。
|
||||||
|
|
||||||
# 前缀表与next数组
|
### 前缀表与next数组
|
||||||
|
|
||||||
很多KMP算法的时间都是使用next数组来做回退操作,那么next数组与前缀表有什么关系呢?
|
很多KMP算法的时间都是使用next数组来做回退操作,那么next数组与前缀表有什么关系呢?
|
||||||
|
|
||||||
@ -217,7 +217,7 @@ next数组就可以是前缀表,但是很多实现都是把前缀表统一减
|
|||||||
|
|
||||||
后面我会提供两种不同的实现代码,大家就明白了。
|
后面我会提供两种不同的实现代码,大家就明白了。
|
||||||
|
|
||||||
# 使用next数组来匹配
|
### 使用next数组来匹配
|
||||||
|
|
||||||
**以下我们以前缀表统一减一之后的next数组来做演示**。
|
**以下我们以前缀表统一减一之后的next数组来做演示**。
|
||||||
|
|
||||||
@ -229,7 +229,7 @@ next数组就可以是前缀表,但是很多实现都是把前缀表统一减
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
# 时间复杂度分析
|
### 时间复杂度分析
|
||||||
|
|
||||||
其中n为文本串长度,m为模式串长度,因为在匹配的过程中,根据前缀表不断调整匹配的位置,可以看出匹配的过程是O(n),之前还要单独生成next数组,时间复杂度是O(m)。所以整个KMP算法的时间复杂度是O(n+m)的。
|
其中n为文本串长度,m为模式串长度,因为在匹配的过程中,根据前缀表不断调整匹配的位置,可以看出匹配的过程是O(n),之前还要单独生成next数组,时间复杂度是O(m)。所以整个KMP算法的时间复杂度是O(n+m)的。
|
||||||
|
|
||||||
@ -239,7 +239,7 @@ next数组就可以是前缀表,但是很多实现都是把前缀表统一减
|
|||||||
|
|
||||||
都知道使用KMP算法,一定要构造next数组。
|
都知道使用KMP算法,一定要构造next数组。
|
||||||
|
|
||||||
# 构造next数组
|
### 构造next数组
|
||||||
|
|
||||||
我们定义一个函数getNext来构建next数组,函数参数为指向next数组的指针,和一个字符串。 代码如下:
|
我们定义一个函数getNext来构建next数组,函数参数为指向next数组的指针,和一个字符串。 代码如下:
|
||||||
|
|
||||||
@ -338,7 +338,7 @@ void getNext(int* next, const string& s){
|
|||||||
|
|
||||||
得到了next数组之后,就要用这个来做匹配了。
|
得到了next数组之后,就要用这个来做匹配了。
|
||||||
|
|
||||||
# 使用next数组来做匹配
|
### 使用next数组来做匹配
|
||||||
|
|
||||||
在文本串s里 找是否出现过模式串t。
|
在文本串s里 找是否出现过模式串t。
|
||||||
|
|
||||||
@ -403,7 +403,7 @@ for (int i = 0; i < s.size(); i++) { // 注意i就从0开始
|
|||||||
|
|
||||||
此时所有逻辑的代码都已经写出来了,力扣 28.实现strStr 题目的整体代码如下:
|
此时所有逻辑的代码都已经写出来了,力扣 28.实现strStr 题目的整体代码如下:
|
||||||
|
|
||||||
# 前缀表统一减一 C++代码实现
|
### 前缀表统一减一 C++代码实现
|
||||||
|
|
||||||
```CPP
|
```CPP
|
||||||
class Solution {
|
class Solution {
|
||||||
@ -447,7 +447,7 @@ public:
|
|||||||
* 时间复杂度: O(n + m)
|
* 时间复杂度: O(n + m)
|
||||||
* 空间复杂度: O(m), 只需要保存字符串needle的前缀表
|
* 空间复杂度: O(m), 只需要保存字符串needle的前缀表
|
||||||
|
|
||||||
# 前缀表(不减一)C++实现
|
### 前缀表(不减一)C++实现
|
||||||
|
|
||||||
那么前缀表就不减一了,也不右移的,到底行不行呢?
|
那么前缀表就不减一了,也不右移的,到底行不行呢?
|
||||||
|
|
||||||
@ -546,7 +546,7 @@ public:
|
|||||||
* 空间复杂度: O(m)
|
* 空间复杂度: O(m)
|
||||||
|
|
||||||
|
|
||||||
# 总结
|
## 总结
|
||||||
|
|
||||||
我们介绍了什么是KMP,KMP可以解决什么问题,然后分析KMP算法里的next数组,知道了next数组就是前缀表,再分析为什么要是前缀表而不是什么其他表。
|
我们介绍了什么是KMP,KMP可以解决什么问题,然后分析KMP算法里的next数组,知道了next数组就是前缀表,再分析为什么要是前缀表而不是什么其他表。
|
||||||
|
|
||||||
@ -563,8 +563,7 @@ public:
|
|||||||
|
|
||||||
## 其他语言版本
|
## 其他语言版本
|
||||||
|
|
||||||
|
### Java:
|
||||||
Java:
|
|
||||||
|
|
||||||
```Java
|
```Java
|
||||||
class Solution {
|
class Solution {
|
||||||
@ -691,8 +690,9 @@ class Solution {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Python3:
|
### Python3:
|
||||||
(版本一)前缀表(减一)
|
(版本一)前缀表(减一)
|
||||||
|
|
||||||
```python
|
```python
|
||||||
class Solution:
|
class Solution:
|
||||||
def getNext(self, next, s):
|
def getNext(self, next, s):
|
||||||
@ -783,7 +783,7 @@ class Solution:
|
|||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Go:
|
### Go:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// 方法一:前缀表使用减1实现
|
// 方法一:前缀表使用减1实现
|
||||||
@ -871,7 +871,7 @@ func strStr(haystack string, needle string) int {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
JavaScript版本
|
### JavaScript:
|
||||||
|
|
||||||
> 前缀表统一减一
|
> 前缀表统一减一
|
||||||
|
|
||||||
@ -959,7 +959,7 @@ var strStr = function (haystack, needle) {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
TypeScript版本:
|
### TypeScript:
|
||||||
|
|
||||||
> 前缀表统一减一
|
> 前缀表统一减一
|
||||||
|
|
||||||
@ -1036,7 +1036,7 @@ function strStr(haystack: string, needle: string): number {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Swift 版本
|
### Swift:
|
||||||
|
|
||||||
> 前缀表统一减一
|
> 前缀表统一减一
|
||||||
|
|
||||||
@ -1196,7 +1196,7 @@ func strStr(_ haystack: String, _ needle: String) -> Int {
|
|||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
PHP:
|
### PHP:
|
||||||
|
|
||||||
> 前缀表统一减一
|
> 前缀表统一减一
|
||||||
```php
|
```php
|
||||||
@ -1272,7 +1272,7 @@ function getNext(&$next, $s){
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Rust:
|
### Rust:
|
||||||
|
|
||||||
> 前缀表统一不减一
|
> 前缀表统一不减一
|
||||||
```Rust
|
```Rust
|
||||||
@ -1362,4 +1362,3 @@ impl Solution {
|
|||||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user