Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit fd1e316

Browse files
committed
feat: update solutions to lc problem: No.0028
No.0028.Find the Index of the First Occurrence in a String
1 parent b33f894 commit fd1e316

File tree

4 files changed

+133
-103
lines changed

4 files changed

+133
-103
lines changed

‎solution/0000-0099/0028.Find the Index of the First Occurrence in a String/README.md‎

Lines changed: 56 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,22 @@
4040

4141
<!-- 这里可写通用的实现逻辑 -->
4242

43+
**方法一:遍历**
44+
45+
以字符串 `haystack` 的每一个字符为起点与字符串 `needle` 进行比较,若发现能够匹配的索引,直接返回即可。
46+
47+
假设字符串 `haystack` 长度为 `n`,字符串 `needle` 长度为 `m`,则时间复杂度为 $O((n-m) \times m),ドル空间复杂度 $O(1)$。
48+
49+
**方法二:Rabin-Karp 字符串匹配算法**
50+
51+
[Rabin-Karp 算法](https://zh.wikipedia.org/zh-hans/%E6%8B%89%E5%AE%BE-%E5%8D%A1%E6%99%AE%E7%AE%97%E6%B3%95)本质上是利用滑动窗口配合哈希函数对固定长度的字符串哈希之后进行比较,可以将比较两个字符串是否相同的时间复杂度降为 $O(1)$。
52+
53+
假设字符串 `haystack` 长度为 `n`,字符串 `needle` 长度为 `m`,则时间复杂度为 $O(n+m),ドル空间复杂度 $O(1)$。
54+
55+
**方法三:KMP 字符串匹配算法**
56+
57+
假设字符串 `haystack` 长度为 `n`,字符串 `needle` 长度为 `m`,则时间复杂度为 $O(n+m),ドル空间复杂度 $O(m)$。
58+
4359
<!-- tabs:start -->
4460

4561
### **Python3**
@@ -48,22 +64,11 @@
4864

4965
```python
5066
class Solution:
51-
def strStr(self, haystack, needle):
52-
"""
53-
:type haystack: str
54-
:type needle: str
55-
:rtype: int
56-
"""
57-
for i in range(len(haystack) - len(needle) + 1):
58-
p = i
59-
q = 0
60-
while p < len(haystack) and q < len(needle) and haystack[p] == needle[q]:
61-
p += 1
62-
q += 1
63-
64-
if q == len(needle):
67+
def strStr(self, haystack: str, needle: str) -> int:
68+
n, m = len(haystack), len(needle)
69+
for i in range(n-m+1):
70+
if haystack[i:i+m] == needle:
6571
return i
66-
6772
return -1
6873
```
6974

@@ -177,30 +182,47 @@ public class Solution {
177182

178183
### **Go**
179184

185+
遍历:
186+
180187
```go
181188
func strStr(haystack string, needle string) int {
182-
switch {
183-
case len(needle) == 0:
184-
return 0
185-
case len(needle) > len(haystack):
186-
return -1
187-
case len(needle) == len(haystack):
188-
if needle == haystack {
189-
return 0
189+
n, m := len(haystack), len(needle)
190+
for i := 0; i <= n-m; i++ {
191+
if haystack[i:i+m] == needle {
192+
return i
190193
}
191-
return -1
192194
}
193-
cursor := 0
194-
for i := 0; i < len(haystack); i++ {
195-
if haystack[i] == needle[cursor] {
196-
cursor++
197-
if cursor == len(needle) {
198-
return i - cursor + 1
199-
}
200-
} else {
201-
i -= cursor
202-
cursor = 0
195+
return -1
196+
}
197+
```
198+
199+
Rabin-Karp 字符串匹配算法:
200+
201+
```go
202+
func strStr(haystack string, needle string) int {
203+
n, m := len(haystack), len(needle)
204+
sha, target, left, right, mod := 0, 0, 0, 0, 1<<31-1
205+
multi := 1
206+
for i := 0; i < m; i++ {
207+
target = (target*256%mod + int(needle[i])) % mod
208+
}
209+
for i := 1; i < m; i++ {
210+
multi = multi * 256 % mod
211+
}
212+
213+
for ; right < n; right++ {
214+
sha = (sha*256%mod + int(haystack[right])) % mod
215+
if right-left+1 < m {
216+
continue
217+
}
218+
// 此时 left~right 的长度已经为 needle 的长度 m 了,只需要比对 sha 值与 target 是否一致即可
219+
// 为避免 hash 冲突,还需要确保 haystack[left:right+1] 与 needle 相同
220+
if sha == target && haystack[left:right+1] == needle {
221+
return left
203222
}
223+
// 未匹配成功,left 右移一位
224+
sha = (sha - (int(haystack[left])*multi)%mod + mod) % mod
225+
left++
204226
}
205227
return -1
206228
}

‎solution/0000-0099/0028.Find the Index of the First Occurrence in a String/README_EN.md‎

Lines changed: 52 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -34,28 +34,29 @@ The first occurrence is at index 0, so we return 0.
3434

3535
## Solutions
3636

37+
**Approach 1: Traverse**
38+
39+
Time complexity $O((n-m) \times m),ドル Space complexity $O(1)$.
40+
41+
**Approach 2: Rabin-Karp**
42+
43+
Time complexity $O(n+m),ドル Space complexity $O(1)$.
44+
45+
**Approach 3: KMP**
46+
47+
Time complexity $O(n+m),ドル Space complexity $O(m)$.
48+
3749
<!-- tabs:start -->
3850

3951
### **Python3**
4052

4153
```python
4254
class Solution:
43-
def strStr(self, haystack, needle):
44-
"""
45-
:type haystack: str
46-
:type needle: str
47-
:rtype: int
48-
"""
49-
for i in range(len(haystack) - len(needle) + 1):
50-
p = i
51-
q = 0
52-
while p < len(haystack) and q < len(needle) and haystack[p] == needle[q]:
53-
p += 1
54-
q += 1
55-
56-
if q == len(needle):
55+
def strStr(self, haystack: str, needle: str) -> int:
56+
n, m = len(haystack), len(needle)
57+
for i in range(n-m+1):
58+
if haystack[i:i+m] == needle:
5759
return i
58-
5960
return -1
6061
```
6162

@@ -167,30 +168,47 @@ public class Solution {
167168

168169
### **Go**
169170

171+
Traverse:
172+
170173
```go
171174
func strStr(haystack string, needle string) int {
172-
switch {
173-
case len(needle) == 0:
174-
return 0
175-
case len(needle) > len(haystack):
176-
return -1
177-
case len(needle) == len(haystack):
178-
if needle == haystack {
179-
return 0
175+
n, m := len(haystack), len(needle)
176+
for i := 0; i <= n-m; i++ {
177+
if haystack[i:i+m] == needle {
178+
return i
180179
}
181-
return -1
182180
}
183-
cursor := 0
184-
for i := 0; i < len(haystack); i++ {
185-
if haystack[i] == needle[cursor] {
186-
cursor++
187-
if cursor == len(needle) {
188-
return i - cursor + 1
189-
}
190-
} else {
191-
i -= cursor
192-
cursor = 0
181+
return -1
182+
}
183+
```
184+
185+
Rabin-Karp:
186+
187+
```go
188+
func strStr(haystack string, needle string) int {
189+
n, m := len(haystack), len(needle)
190+
sha, target, left, right, mod := 0, 0, 0, 0, 1<<31-1
191+
multi := 1
192+
for i := 0; i < m; i++ {
193+
target = (target*256%mod + int(needle[i])) % mod
194+
}
195+
for i := 1; i < m; i++ {
196+
multi = multi * 256 % mod
197+
}
198+
199+
for ; right < n; right++ {
200+
sha = (sha*256%mod + int(haystack[right])) % mod
201+
if right-left+1 < m {
202+
continue
203+
}
204+
// 此时 left~right 的长度已经为 needle 的长度 m 了,只需要比对 sha 值与 target 是否一致即可
205+
// 为避免 hash 冲突,还需要确保 haystack[left:right+1] 与 needle 相同
206+
if sha == target && haystack[left:right+1] == needle {
207+
return left
193208
}
209+
// 未匹配成功,left 右移一位
210+
sha = (sha - (int(haystack[left])*multi)%mod + mod) % mod
211+
left++
194212
}
195213
return -1
196214
}
Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,27 @@
11
func strStr(haystack string, needle string) int {
2-
switch {
3-
case len(needle) == 0:
4-
return 0
5-
case len(needle) > len(haystack):
6-
return -1
7-
case len(needle) == len(haystack):
8-
if needle == haystack {
9-
return 0
10-
}
11-
return -1
2+
n, m := len(haystack), len(needle)
3+
sha, target, left, right, mod := 0, 0, 0, 0, 1<<31-1
4+
multi := 1
5+
for i := 0; i < m; i++ {
6+
target = (target*256%mod + int(needle[i])) % mod
7+
}
8+
for i := 1; i < m; i++ {
9+
multi = multi * 256 % mod
1210
}
13-
cursor:=0
14-
for i:=0; i < len(haystack); i++ {
15-
ifhaystack[i] ==needle[cursor] {
16-
cursor++
17-
ifcursor==len(needle) {
18-
returni-cursor+1
19-
}
20-
} else {
21-
i-=cursor
22-
cursor=0
11+
12+
for ; right < n; right++ {
13+
sha= (sha*256%mod+int(haystack[right])) %mod
14+
ifright-left+1<m {
15+
continue
16+
}
17+
// 此时 left~right 的长度已经为 needle 的长度 m 了,只需要比对 sha 值与 target 是否一致即可
18+
// 为避免 hash 冲突,还需要确保 haystack[left:right+1] 与 needle 相同
19+
ifsha==target&&haystack[left:right+1] ==needle {
20+
returnleft
2321
}
22+
// 未匹配成功,left 右移一位
23+
sha = (sha - (int(haystack[left])*multi)%mod + mod) % mod
24+
left++
2425
}
2526
return -1
2627
}
Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,7 @@
11
class Solution:
2-
def strStr(self, haystack, needle):
3-
"""
4-
:type haystack: str
5-
:type needle: str
6-
:rtype: int
7-
"""
8-
for i in range(len(haystack) - len(needle) + 1):
9-
p = i
10-
q = 0
11-
while p < len(haystack) and q < len(needle) and haystack[p] == needle[q]:
12-
p += 1
13-
q += 1
14-
15-
if q == len(needle):
2+
def strStr(self, haystack: str, needle: str) -> int:
3+
n, m = len(haystack), len(needle)
4+
for i in range(n-m+1):
5+
if haystack[i:i+m] == needle:
166
return i
17-
187
return -1

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /