-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
192 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
# 第四章 字符串part02 | ||
今日任务 | ||
|
||
●28. 实现 strStr() | ||
●459.重复的子字符串 | ||
●字符串总结 | ||
●双指针回顾 | ||
|
||
详细布置 | ||
|
||
## 28. 实现 strStr() (本题可以跳过) | ||
|
||
因为KMP算法很难,大家别奢求 一次就把kmp全理解了,大家刚学KMP一定会有各种各样的疑问,先留着,别期望立刻啃明白,第一遍了解大概思路,二刷的时候,再看KMP会 好懂很多。 | ||
|
||
或者说大家可以放弃一刷可以不看KMP,今天来回顾一下之前的算法题目就可以。 | ||
|
||
因为大家 算法能力还没到,细扣 很难的算法,会把自己绕进去,就算别人给解释,只会激发出更多的问题和疑惑。所以大家先了解大体过程,知道这么回事, 等自己有 算法基础和思维了,在看多看几遍视频,慢慢就理解了。 | ||
|
||
题目链接/文章讲解/视频讲解:https://programmercarl.com/0028.%E5%AE%9E%E7%8E%B0strStr.html | ||
|
||
## 459.重复的子字符串 (本题可以跳过) | ||
|
||
本题算是KMP算法的一个应用,不过 对KMP了解不够熟练的话,理解本题就难很多。 | ||
我的建议是 KMP和本题,一刷的时候 ,可以适当放过,了解怎么回事就行,二刷的时候再来硬啃 | ||
|
||
题目链接/文章讲解/视频讲解:https://programmercarl.com/0459.%E9%87%8D%E5%A4%8D%E7%9A%84%E5%AD%90%E5%AD%97%E7%AC%A6%E4%B8%B2.html | ||
|
||
## 字符串总结 | ||
|
||
比较简单,大家读一遍就行 | ||
|
||
题目链接/文章讲解:https://programmercarl.com/%E5%AD%97%E7%AC%A6%E4%B8%B2%E6%80%BB%E7%BB%93.html | ||
|
||
## 双指针回顾 | ||
|
||
此时我们已经做过10到双指针的题目了,来一起回顾一下,大家自己也总结一下双指针的心得 | ||
|
||
文章讲解:https://programmercarl.com/%E5%8F%8C%E6%8C%87%E9%92%88%E6%80%BB%E7%BB%93.html | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
# 28. 找出字符串中第一个匹配项的下标 | ||
|
||
## 题目描述 | ||
|
||
给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标(下标从 0 开始)。如果 needle 不是 haystack 的一部分,则返回 -1 。 | ||
|
||
## 解题思路 | ||
|
||
KMP 对我来说太烧脑了,不得不写点笔记 | ||
|
||
KMP的主要思想是当出现字符串不匹配时,可以知道一部分之前已经匹配的文本内容,可以利用这些信息避免从头再去做匹配了 | ||
|
||
前缀是指**不包含最后一个字符**的所有**以第一个字符开头**的连续子串。 | ||
|
||
后缀是指**不包含第一个字符**的所有**以最后一个字符结尾**的连续子串。 | ||
|
||
因为前缀表要求的就是相同前后缀的长度 | ||
|
||
定义两个指针i和j | ||
- j指向前缀末尾位置(不包含) | ||
- i指向后缀末尾位置(包含) | ||
|
||
next[i] 表示 i(**包括i**)之前最长相等的前后缀长度(其实就是j) | ||
|
||
```cpp | ||
void getNext(int* next, const string& s){ | ||
int j = -1; | ||
next[0] = j; | ||
for(int i = 1; i < s.size(); i++) { // 对当前字符串,j指向上一个字符串的最大前后缀的位置 | ||
while (j >= 0 && s[i] != s[j + 1]) { // 前后缀不相同了 | ||
j = next[j]; // 向前回退 | ||
} | ||
if (s[i] == s[j + 1]) { // 找到相同的前后缀 | ||
j ++ ; | ||
} | ||
next[i] = j; // 赋值 | ||
} | ||
} | ||
``` | ||
## 举例 | ||
```plaintext | ||
j | ||
aabaabaaf | ||
i | ||
012345678 | ||
0 01234 | ||
``` | ||
|
||
|
||
```rust | ||
struct Solution {} | ||
|
||
impl Solution { | ||
pub fn str_str(haystack: String, needle: String) -> i32 { | ||
let n = needle.len(); | ||
let mut next = vec![0; n]; | ||
let hay = haystack.chars().collect::<Vec<char>>(); | ||
let s = needle.chars().collect::<Vec<char>>(); | ||
let mut j = 0; | ||
for i in 1..n { | ||
while j >= 1 && s[i] != s[j] { | ||
j = next[j - 1]; | ||
} | ||
if s[i] == s[j] { | ||
j += 1; | ||
} | ||
next[i] = j; // next 表示以i结尾的字符串最大前后缀长度 | ||
} | ||
// dbg!(&next); | ||
// build next ok | ||
if n == 0 { return 0 } | ||
j = 0; | ||
for i in 0..hay.len() { | ||
// dbg!(i, j); | ||
while j >= 1 && hay[i] != s[j] { | ||
j = next[j - 1]; | ||
} | ||
if hay[i] == s[j] { | ||
j += 1; | ||
} | ||
if j == n { | ||
return (i + 1 - n) as i32 | ||
} | ||
} | ||
-1 | ||
} | ||
} | ||
``` | ||
## 学习感想 | ||
|
||
还得学习复习 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
# 459. 重复的子字符串 | ||
|
||
## 题目描述 | ||
|
||
给定一个非空的字符串 s ,检查是否可以通过由它的一个子串重复多次构成。 | ||
|
||
## 解题思路 | ||
|
||
### 例子 | ||
|
||
```plaintext | ||
abcabcabcabc | ||
000123456789 | ||
abaaba | ||
001123 | ||
abacabacabac | ||
001012345678 | ||
abac | ||
0010 | ||
``` | ||
|
||
```rust | ||
|
||
struct Solution {} | ||
|
||
impl Solution { | ||
pub fn repeated_substring_pattern(s: String) -> bool { | ||
let n = s.len(); | ||
let mut next = vec![0; n]; | ||
let s = s.chars().collect::<Vec<char>>(); | ||
let mut j = 0; | ||
for i in 1..n { | ||
while j >= 1 && s[i] != s[j] { | ||
j = next[j - 1]; | ||
} | ||
if s[i] == s[j] { | ||
j += 1; | ||
} | ||
next[i] = j; // next 表示以i结尾的字符串最大前后缀长度 | ||
} | ||
let a = *next.last().unwrap(); | ||
if a == 0 { return false } | ||
let b = n - a; | ||
if n % b != 0 { return false } | ||
else { true } | ||
} | ||
} | ||
|
||
``` | ||
|
||
## 学习感想 | ||
|
||
什么时候该用KMP很懵 |