今日任务
● 28. 实现 strStr()
● 459.重复的子字符串
● 字符串总结
● 双指针回顾
0. KMP算法
- 名称来源
- 发明该算法的三个科学家的名称首字母
- 解决:
- 字符串匹配问题
- 可使用暴力匹配
- 时间复杂度 O(m*n):
- m:文本串长度
- n:模式串长度
- 时间复杂度 O(m*n):
- 可使用暴力匹配
- 字符串匹配问题
- 理论
- 前缀表:
- 功能:可以找到之前已经找到过的内容
- 定义:
- 前后缀都是从前往后读的:都是左右走向
- 前缀:
- 包含首字母不包含尾字母的所有字串
- 从首字母开始,依次递加后一个字母
- 后缀:
- 只包含尾字母不包含首字母的所有字串
- 从尾字母开始,依次递加前一个字母
- 需求:
- 求最长相等前后缀(2个:前缀、后缀)的长度
- 前缀表:
1. 实现 strStr() (本题可以跳过)
关联 leetcode 28. 实现 strStr()
因为KMP算法很难,大家别奢求 一次就把kmp全理解了,大家刚学KMP一定会有各种各样的疑问,先留着,别期望立刻啃明白,第一遍了解大概思路,二刷的时候,再看KMP会 好懂很多。
或者说大家可以放弃一刷可以不看KMP,今天来回顾一下之前的算法题目就可以。
因为大家 算法能力还没到,细扣 很难的算法,会把自己绕进去,就算别人给解释,只会激发出更多的问题和疑惑。所以大家先了解大体过程,知道这么回事, 等自己有 算法基础和思维了,在看多看几遍视频,慢慢就理解了。
题目链接/文章讲解/视频讲解:https://programmercarl.com/0028.实现strStr.html
2. 重复的子字符串 (本题可以跳过)
关联 leetcode 459.重复的子字符串
本题算是KMP算法的一个应用,不过 对KMP了解不够熟练的话,理解本题就难很多。
我的建议是 KMP和本题,一刷的时候 ,可以适当放过,了解怎么回事就行,二刷的时候再来硬啃
题目链接/文章讲解/视频讲解:https://programmercarl.com/0459.重复的子字符串.html
3. 字符串总结
- 若干字符组成的有限序列
- Golang里面的 string 是一个 []rune
- 实现了对 标准 utf8 的兼容
- 库函数的使用
- 非关键部分可以考虑使用
- Golang1.21.0+的库函数不如其他语言丰富,基本都需要自己实现
- 双指针
- 双指针法在数组,链表和字符串中很常用。
- 其实很多数组填充类的问题,都可以先预先给数组扩容带填充后的大小,然后在从后向前进行操作。
- 反转
- 当需要固定规律一段一段去处理字符串的时候,要想想在在for循环的表达式上做做文章。
- 整体、局部反转的使用
- KMP
- 当出现字符串不匹配时,可以知道一部分之前已经匹配的文本内容,可以利用这些信息避免从头再去做匹配了
4. 双指针回顾
- 数组和字符串常用
- 有同向运动和相向运动两种方式
- 除了运动相同步长外,还可以运动不同步长来实现追击的效果
4.1 数组篇
- 使用双指针法才展现出效率的优势:
- 通过两个指针在一个for循环下完成两个for循环的工作。
4.2 字符串篇
- 使用双指针法,定义两个指针(也可以说是索引下标),一个从字符串前面,一个从字符串后面,两个指针同时向中间移动,并交换元素。,时间复杂度是O(n)。
- 降低时间复杂度 O(n^2) —> O(n)
- 注意填充的方向可能导致时间复杂度变化
- 可能导致 处理数据本身外,涉及到其他数据的移动
- 注意填充的方向可能导致时间复杂度变化
4.3 链表篇
- 使用双指针法来翻转链表,只需要改变链表的next指针的指向,直接将链表反转 ,而不用重新定义一个新的链表。
- 使用快慢指针(双指针法),分别定义 fast 和 slow指针,从头结点出发,fast指针每次移动两个节点,slow指针每次移动一个节点,如果 fast 和 slow指针在途中相遇 ,说明这个链表有环。
4.3 N数之和篇
- 通过前后两个指针不算向中间逼近,在一个for循环下完成两个for循环的工作。
- 在一个有序数组内
- for循环内嵌套一个 头尾指针
- 头尾指针构成一个类似滑动窗口,向中间夹逼缩小搜寻范围
- 在一个有序数组内