Skip to content

Commit d758f1e

Browse files
committed
438. Find All Anagrams in a String
1 parent 49ee473 commit d758f1e

File tree

5 files changed

+150
-2
lines changed

5 files changed

+150
-2
lines changed

Leetcode/0438.Find-All-Anagrams-in-a-String/README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
title: Find All Anagrams in a String
3-
tags: Medium
3+
tags: Medium, Sliding Window
44
author: Kimi Tsai <[email protected]>
55
description:
66
---
@@ -36,8 +36,9 @@ s and p consist of lowercase English letters.
3636

3737
## 題目大意
3838
找所有字母異位詞, 就像[全排列](https://github.com/kimi0230/LeetcodeGolang/blob/master/Leetcode/0567.Permutation-in-String/main.go)
39-
39+
給定一個字符串 S 和非空的字符串 P, 找到 S 中所有是 P 得排列, 並返回他的起始 index
4040
## 解題思路
41+
[0567.Permutation-in-String](https://github.com/kimi0230/LeetcodeGolang/blob/master/Leetcode/0567.Permutation-in-String/main.go)類似, 只是把找到的答案記錄起來
4142

4243
## 來源
4344
* https://leetcode.com/problems/find-all-anagrams-in-a-string/
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package findallanagramsinastring
2+
3+
func FindAnagrams(s string, p string) []int {
4+
need, window := make(map[rune]int), make(map[rune]int)
5+
for _, c := range p {
6+
need[c]++
7+
}
8+
9+
left, right := 0, 0
10+
valid := 0
11+
res := []int{} //紀錄結果
12+
for right < len(s) {
13+
c := rune(s[right])
14+
right++
15+
16+
if need[c] > 0 {
17+
window[c]++
18+
if window[c] == need[c] {
19+
valid++
20+
}
21+
}
22+
// fmt.Printf("[%d,%d) \n", left, right)
23+
24+
// 判斷左視窗是否收縮, 看看視窗長度是否同要找的字串的長度
25+
if (right - left) >= len(p) {
26+
if valid == len(need) {
27+
// 想要的字元都找到了, 紀錄index
28+
res = append(res, left)
29+
}
30+
d := rune(s[left])
31+
left++
32+
if need[d] > 0 {
33+
if window[d] == need[d] {
34+
valid--
35+
}
36+
window[d]--
37+
}
38+
}
39+
}
40+
return res
41+
}
42+
43+
// 用 slice 取代 map 來優化
44+
func FindAnagramsSlice(s string, p string) []int {
45+
need := [256]int{}
46+
for _, c := range p {
47+
need[c-'a']++
48+
}
49+
left, right := 0, 0
50+
count := len(p)
51+
res := []int{}
52+
53+
for right < len(s) {
54+
c := s[right] - 'a'
55+
if need[c] > 0 {
56+
count--
57+
}
58+
need[c]--
59+
right++
60+
61+
if count == 0 {
62+
res = append(res, left)
63+
}
64+
65+
if (right - left) >= len(p) {
66+
d := s[left] - 'a'
67+
if need[d] >= 0 {
68+
count++
69+
}
70+
need[d]++
71+
left++
72+
}
73+
}
74+
return res
75+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package findallanagramsinastring
2+
3+
import (
4+
"reflect"
5+
"testing"
6+
)
7+
8+
var tests = []struct {
9+
arg1 string
10+
arg2 string
11+
want []int
12+
}{
13+
{
14+
"cbaebabacd",
15+
"abc",
16+
[]int{0, 6},
17+
},
18+
{
19+
"abab",
20+
"ab",
21+
[]int{0, 1, 2},
22+
},
23+
}
24+
25+
func TestFindAnagrams(t *testing.T) {
26+
for _, tt := range tests {
27+
if got := FindAnagrams(tt.arg1, tt.arg2); !reflect.DeepEqual(got, tt.want) {
28+
t.Errorf("got = %v, want = %v", got, tt.want)
29+
}
30+
}
31+
}
32+
33+
func TestFindAnagramsSlice(t *testing.T) {
34+
for _, tt := range tests {
35+
if got := FindAnagramsSlice(tt.arg1, tt.arg2); !reflect.DeepEqual(got, tt.want) {
36+
t.Errorf("got = %v, want = %v", got, tt.want)
37+
}
38+
}
39+
}
40+
41+
func BenchmarkFindAnagrams(b *testing.B) {
42+
b.ResetTimer()
43+
for i := 0; i < b.N; i++ {
44+
FindAnagrams(tests[0].arg1, tests[0].arg2)
45+
}
46+
}
47+
48+
func BenchmarkFindAnagramsSlice(b *testing.B) {
49+
b.ResetTimer()
50+
for i := 0; i < b.N; i++ {
51+
FindAnagramsSlice(tests[0].arg1, tests[0].arg2)
52+
}
53+
}
54+
55+
/*
56+
go test -benchmem -run=none LeetcodeGolang/Leetcode/0438.Find-All-Anagrams-in-a-String -bench=.
57+
goos: darwin
58+
goarch: amd64
59+
pkg: LeetcodeGolang/Leetcode/0438.Find-All-Anagrams-in-a-String
60+
cpu: Intel(R) Core(TM) i5-8259U CPU @ 2.30GHz
61+
BenchmarkFindAnagrams-8 1572444 690.4 ns/op 24 B/op 2 allocs/op
62+
BenchmarkFindAnagramsSlice-8 11687409 136.9 ns/op 24 B/op 2 allocs/op
63+
PASS
64+
ok LeetcodeGolang/Leetcode/0438.Find-All-Anagrams-in-a-String 4.329s
65+
*/

Leetcode/0567.Permutation-in-String/README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
---
2+
title: Permutation in String
3+
tags: Medium, Sliding Window
4+
author: Kimi Tsai <[email protected]>
5+
description:
6+
---
17
# [567. Permutation in String](https://leetcode.com/problems/permutation-in-string/)
28
tags: Medium, Sliding Window
39

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ void slidingWindow(string s, string t){
164164
| No. | Title | Solution | Difficulty | Time | Space | Topic |
165165
|-----|:-----:|:--------:|------------|------|-------|-------|
166166
| 0209 | [Minimum Size Subarray Sum](https://leetcode.com/problems/minimum-size-subarray-sum/) | [Go](https://github.com/kimi0230/LeetcodeGolang/tree/master/Leetcode/0209.Minimum-Size-Subarray-Sum) | Medium | O(n^2) / O(n) / O(nlog n) | O(1) / O(1) / O(n) | Sliding Window |
167+
| 0438 | [438. Find All Anagrams in a String](https://leetcode.com/problems/find-all-anagrams-in-a-string/) | [Go](https://github.com/kimi0230/LeetcodeGolang/tree/master/Leetcode/0438.Find-All-Anagrams-in-a-String) | Medium | O(n) | O(1) | Sliding Window |
167168
| 0567 | [Permutation in String](https://leetcode.com/problems/permutation-in-string/) | [Go](https://github.com/kimi0230/LeetcodeGolang/tree/master/Leetcode/0567.Permutation-in-String) | Medium | O(n) | O(1) | Sliding Window |
168169

169170
---

0 commit comments

Comments
 (0)