This commit is contained in:
youngyangyang04
2021-06-23 10:51:37 +08:00
parent f8047a82a3
commit e719e4f647
3 changed files with 30 additions and 30 deletions

View File

@ -59,7 +59,7 @@ KMP的经典思想就是:**当出现字符串不匹配时,可以记录一部
* 总结
读完本篇可以顺便把leetcode上28.实现strStr()题目做了。
读完本篇可以顺便把leetcode上28.实现strStr()题目做了。
# 什么是KMP
@ -126,16 +126,15 @@ next数组就是一个前缀表prefix table
# 最长公共前后缀?
文章中字符串的前缀是指不包含最后一个字符的所有以第一个字符开头的连续子串
文章中字符串的**前缀是指不包含最后一个字符的所有以第一个字符开头的连续子串**。
后缀是指不包含第一个字符的所有以最后一个字符结尾的连续子串。
**后缀是指不包含第一个字符的所有以最后一个字符结尾的连续子串**
**正确理解什么是前缀什么是后缀很重要**
**正确理解什么是前缀什么是后缀很重要**!
那么网上清一色都说 “kmp 最长公共前后缀” 又是什么回事呢?
我查了一遍 算法导论 和 算法4里KMP的章节都没有提到 “最长公共前后缀”这个词,也不知道从哪里来了,我理解是用“最长相等前后缀” 准确一些。
我查了一遍 算法导论 和 算法4里KMP的章节都没有提到 “最长公共前后缀”这个词,也不知道从哪里来了,我理解是用“最长相等前后缀” 更准确一些。
**因为前缀表要求的就是相同前后缀的长度。**
@ -220,7 +219,7 @@ next数组就可以是前缀表但是很多实现都是把前缀表统一减
# 使用next数组来匹配
以下我们以前缀表统一减一之后的next数组来做演示。
**以下我们以前缀表统一减一之后的next数组来做演示**
有了next数组就可以根据next数组来 匹配文本串s和模式串t了。
@ -236,7 +235,7 @@ next数组就可以是前缀表但是很多实现都是把前缀表统一减
暴力的解法显而易见是O(n * m),所以**KMP在字符串匹配中极大的提高的搜索的效率。**
为了和[字符串KMP是时候上场了一文读懂系列](https://mp.weixin.qq.com/s/70OXnZ4Ez29CKRrUpVJmug)字符串命名统一方便大家理解以下文章统称haystack为文本串, needle为模式串。
为了和力扣题目28.实现strStr保持一致方便大家理解以下文章统称haystack为文本串, needle为模式串。
都知道使用KMP算法一定要构造next数组。
@ -402,7 +401,7 @@ for (int i = 0; i < s.size(); i++) { // 注意i就从0开始
}
```
此时所有逻辑的代码都已经写出来了,本题整体代码如下:
此时所有逻辑的代码都已经写出来了,力扣 28.实现strStr 题目的整体代码如下:
# 前缀表统一减一 C++代码实现
@ -448,7 +447,9 @@ public:
# 前缀表不减一C++实现
那么前缀表就不减一了,也不右移的,到底行不行呢?行!
那么前缀表就不减一了,也不右移的,到底行不行呢?
**行!**
我之前说过这仅仅是KMP算法实现上的问题如果就直接使用前缀表可以换一种回退方式找j=next[j-1] 来进行回退。
@ -544,7 +545,7 @@ public:
我们介绍了什么是KMPKMP可以解决什么问题然后分析KMP算法里的next数组知道了next数组就是前缀表再分析为什么要是前缀表而不是什么其他表。
接着从给出的模式串中,我们一步一步的推导出了前缀表,得出前缀表无论是统一减一还是不同意减一得到的next数组仅仅是kmp的实现方式的不同。
接着从给出的模式串中我们一步一步的推导出了前缀表得出前缀表无论是统一减一还是不减一得到的next数组仅仅是kmp的实现方式的不同。
其中还分析了KMP算法的时间复杂度并且和暴力方法做了对比。
@ -815,4 +816,4 @@ func strStr(haystack string, needle string) int {
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
* B站视频[代码随想录](https://space.bilibili.com/525438321)
* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>

View File

@ -15,10 +15,10 @@ https://leetcode-cn.com/problems/implement-queue-using-stacks/
使用栈实现队列的下列操作:
push(x) -- 将一个元素放入队列的尾部。
pop() -- 从队列首部移除元素。
peek() -- 返回队列首部的元素。
empty() -- 返回队列是否为空。
push(x) -- 将一个元素放入队列的尾部。
pop() -- 从队列首部移除元素。
peek() -- 返回队列首部的元素。
empty() -- 返回队列是否为空。
示例:
@ -46,18 +46,18 @@ queue.empty(); // 返回 false
下面动画模拟以下队列的执行过程如下:
执行语句:
queue.push(1);
queue.push(2);
queue.pop(); **注意此时的输出栈的操作**
queue.push(3);
queue.push(4);
queue.pop();
queue.pop();**注意此时的输出栈的操作**
queue.pop();
queue.empty();
执行语句:
queue.push(1);
queue.push(2);
queue.pop(); **注意此时的输出栈的操作**
queue.push(3);
queue.push(4);
queue.pop();
queue.pop();**注意此时的输出栈的操作**
queue.pop();
queue.empty();
![232.用栈实现队列版本2](https://code-thinking.cdn.bcebos.com/gifs/232.%E7%94%A8%E6%A0%88%E5%AE%9E%E7%8E%B0%E9%98%9F%E5%88%97%E7%89%88%E6%9C%AC2.gif)
![232.用栈实现队列版本2](https://code-thinking.cdn.bcebos.com/gifs/232.用栈实现队列版本2.gif)
在push数据的时候只要数据放进输入栈就好**但在pop的时候操作就复杂一些输出栈如果为空就把进栈数据全部导入进来注意是全部导入**,再从出栈弹出数据,如果输出栈不为空,则直接从出栈弹出数据就可以了。
@ -125,8 +125,6 @@ public:
## 其他语言版本
Java

View File

@ -26,7 +26,8 @@
拿示例一A = [1,4,2], B = [1,2,4]为例,相交情况如图:
![1035.不相交的线](https://img-blog.csdnimg.cn/20210321164517460.png)
![](https://gitee.com/programmercarl/pics/raw/master/pic1/20210527113415.png)
其实也就是说A和B的最长公共子序列是[1,4]长度为2。 这个公共子序列指的是相对顺序不变即数字4在字符串A中数字1的后面那么数字4也应该在字符串B数字1的后面