Skip to content

Commit 6dfc2d7

Browse files
aQuaaQua
aQua
authored and
aQua
committed
finish Problem 38
1 parent a3966bf commit 6dfc2d7

File tree

3 files changed

+22
-46
lines changed

3 files changed

+22
-46
lines changed

Algorithms/0038.count-and-say/README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,9 @@ Output: "1211"
3131
```
3232

3333
## 解题思路
34+
利用[]byte记录上一次出现的次数和元素。
3435

36+
详见注释
3537

3638
## 总结
37-
38-
39+
使用辅助结果,比如切片或者映射记录信息,可以极大地加快程序
Lines changed: 19 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,33 @@
11
package Problem0038
22

3-
import (
4-
"strconv"
5-
)
6-
73
func countAndSay(n int) string {
8-
if n == 1 {
9-
return "1"
10-
}
11-
return say(countAndSay(n - 1))
12-
}
4+
buf := []byte{'1'}
135

14-
func say(s string) string {
15-
res := ""
16-
17-
words := split(s)
18-
for _, w := range words {
19-
res += strconv.Itoa(len(w)) + w[0:1]
6+
for n > 1 {
7+
buf = say(buf)
8+
n--
209
}
2110

22-
return res
11+
return string(buf)
2312
}
2413

25-
func split(s string) []string {
26-
res := []string{}
27-
i, j := 0, 1
14+
func say(buf []byte) []byte {
15+
// res 长度不会超过 buf 的两倍,所以,可以事先指定容量,加快append的速度
16+
res := make([]byte, 0, len(buf)*2)
2817

29-
for j < len(s) {
30-
if s[i] != s[j] {
31-
res = append(res, s[i:j])
32-
i = j
18+
i, j := 0, 1
19+
for i < len(buf) {
20+
// 利用 j ,找到下一个不同的元素
21+
for j < len(buf) && buf[j] == buf[i] {
22+
j++
3323
}
34-
j++
35-
}
3624

37-
res = append(res, s[i:])
25+
// res 中 res[i] 表示 res[i+1] 的个数,i 为0,2,4,6,...
26+
res = append(res, byte(j-i+'0'), buf[i])
27+
28+
// 移动 i 到 j
29+
i = j
30+
}
3831

3932
return res
4033
}

Algorithms/0038.count-and-say/count-and-say_test.go

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -79,21 +79,3 @@ func Test_Problem0038(t *testing.T) {
7979
ast.Equal(a.one, countAndSay(p.one), "输入:%v", p)
8080
}
8181
}
82-
83-
func Test_say(t *testing.T) {
84-
ast := assert.New(t)
85-
86-
ast.Equal("1211", say("21"), "没有把 21 说成 1211")
87-
}
88-
89-
func Test_split(t *testing.T) {
90-
ast := assert.New(t)
91-
92-
actual := split("333221")
93-
expected := []string{"333", "22", "1"}
94-
ast.Equal(expected, actual, "没能分隔字符串")
95-
96-
actual = split("11")
97-
expected = []string{"11"}
98-
ast.Equal(expected, actual, "没能分隔字符串")
99-
}

0 commit comments

Comments
 (0)