Skip to content
This repository was archived by the owner on Sep 20, 2023. It is now read-only.

Commit 9b8fba7

Browse files
committed
Merge branch 'master' into develop
2 parents cef8f03 + dfa0854 commit 9b8fba7

12 files changed

+216
-58
lines changed

Algorithms/0337.house-robber-iii/house-robber-iii_test.go

+51-14
Original file line numberDiff line numberDiff line change
@@ -4,32 +4,28 @@ import (
44
"fmt"
55
"testing"
66

7-
"github.com/aQuaYi/LeetCode-in-Go/kit"
8-
97
"github.com/stretchr/testify/assert"
108
)
119

1210
// tcs is testcase slice
1311
var tcs = []struct {
14-
pre, in []int
15-
ans int
12+
nums []int
13+
ans int
1614
}{
1715

16+
// 用 0 表示 nil
1817
{
19-
[]int{5, 2, 4, 1, 3, 1000},
20-
[]int{2, 4, 5, 1, 3, 1000},
21-
1009,
18+
[]int{4, 1, 0, 2, 0, 3},
19+
7,
2220
},
2321

2422
{
25-
[]int{5, 2, 4, 1, 3},
26-
[]int{2, 4, 5, 1, 3},
27-
12,
23+
[]int{3, 2, 3, 0, 3, 0, 1},
24+
7,
2825
},
2926

3027
{
31-
[]int{3, 4, 1, 3, 5, 1},
32-
[]int{1, 4, 3, 3, 5, 1},
28+
[]int{3, 4, 5, 1, 3, 0, 1},
3329
9,
3430
},
3531

@@ -41,16 +37,57 @@ func Test_rob(t *testing.T) {
4137

4238
for _, tc := range tcs {
4339
fmt.Printf("~~%v~~\n", tc)
44-
root := kit.PreIn2Tree(tc.pre, tc.in)
40+
root := &TreeNode{}
41+
initTree(tc.nums, []*TreeNode{}, root)
4542
ast.Equal(tc.ans, rob(root), "输入:%v", tc)
4643
}
4744
}
4845

4946
func Benchmark_rob(b *testing.B) {
5047
for i := 0; i < b.N; i++ {
5148
for _, tc := range tcs {
52-
root := kit.PreIn2Tree(tc.pre, tc.in)
49+
root := &TreeNode{}
50+
initTree(tc.nums, []*TreeNode{}, root)
5351
rob(root)
5452
}
5553
}
5654
}
55+
56+
// 创建二叉树
57+
func initTree(nums []int, parents []*TreeNode, root *TreeNode) {
58+
if len(nums) == 0 {
59+
return
60+
}
61+
62+
if len(parents) == 0 {
63+
if nums[0] != 0 {
64+
root.Val = nums[0]
65+
parents = append(parents, root)
66+
initTree(nums[1:], parents, root)
67+
}
68+
69+
return
70+
}
71+
72+
newParents := make([]*TreeNode, 0, len(parents)*2)
73+
for _, parent := range parents {
74+
75+
if nums[0] != 0 {
76+
parent.Left = &TreeNode{Val: nums[0]}
77+
newParents = append(newParents, parent.Left)
78+
}
79+
80+
if len(nums) == 1 {
81+
return
82+
}
83+
84+
if nums[1] != 0 {
85+
parent.Right = &TreeNode{Val: nums[1]}
86+
newParents = append(newParents, parent.Right)
87+
}
88+
89+
nums = nums[2:]
90+
}
91+
92+
initTree(nums, newParents, root)
93+
}
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
11
package problem0342
22

3-
func isPowerOfFour(n int) bool {
4-
if n < 1 {
3+
func isPowerOfFour(num int) bool {
4+
if num <= 0 {
55
return false
66
}
77

8-
for n%4 == 0 {
9-
n /= 4
8+
// 如果 num 不是2的N次方, 那么也不是4的N次方
9+
if num&(num-1) != 0 {
10+
return false
1011
}
11-
12-
return n == 1
12+
13+
// 过滤
14+
if num&0x55555555 == 0 {
15+
return false
16+
}
17+
18+
return true
1319
}

Algorithms/0342.power-of-four/power-of-four_test.go

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ var tcs = []struct {
1313
ans bool
1414
}{
1515

16+
{2, false},
1617
{16, true},
1718
{5, false},
1819
{-5, false},

Algorithms/0686.repeated-string-match/repeated-string-match.go

+27-9
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,33 @@
11
package problem0686
22

3-
import "strings"
4-
5-
func repeatedStringMatch(a string, b string) int {
6-
times := max(len(b)/len(a), 1)
7-
8-
if strings.Contains(strings.Repeat(a, times), b) {
9-
return times
3+
func repeatedStringMatch(A string, B string) int {
4+
// ref: https://leetcode.com/problems/repeated-string-match/discuss/108084/C%2B%2B-4-lines-O(m-*-n)-or-O(1)-and-KMP-O(m-%2B-n)-or-O(n)
5+
n, m := len(A), len(B)
6+
prefTable := make([]int, m+1)
7+
for sp, pp := 1, 0; sp < m; {
8+
if B[pp] == B[sp] {
9+
sp++
10+
pp++
11+
prefTable[sp] = pp
12+
} else if pp == 0 {
13+
sp++
14+
prefTable[sp] = pp
15+
} else {
16+
pp = prefTable[pp]
17+
}
1018
}
11-
if strings.Contains(strings.Repeat(a, times+1), b) {
12-
return times + 1
19+
20+
for i, j := 0, 0; i < n; i, j = i+max(1, j-prefTable[j]), prefTable[j] {
21+
for j < m && A[(i+j)%n] == B[j] {
22+
j++
23+
}
24+
if j == m {
25+
if (i+j)%n == 0 {
26+
return (i + j) / n
27+
} else {
28+
return (i+j)/n + 1
29+
}
30+
}
1331
}
1432
return -1
1533
}

Algorithms/0686.repeated-string-match/repeated-string-match_test.go

+5
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,11 @@ var tcs = []struct {
7979
2,
8080
},
8181

82+
{
83+
"abc",
84+
"cabcabca",
85+
4,
86+
},
8287
// 可以有多个 testcase
8388
}
8489

Helper/README.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@
66
1.`LeetCode-in-Go`目录下,添加文本文件`config.toml`
77
1. 把以下内容复制到`config.toml`中。
88
1.`config.toml`中的`test`分别修改为你的 leetcode `用户名``密码`
9+
1. 去 leetcode 登录后,把网站 cookie 复制 (有洁癖者只要复制 LEETCODE_SESSION 就够了) 并替换 `config.toml`中的`Cookie`
910

1011
```toml
11-
Login="test"
12+
Username="test"
1213
Password="test"
14+
Cookie="LEETCODE_SESSION=XXXXXXXXX;"
1315
```

Helper/buildProblemDir.go

+16-11
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"fmt"
55
"log"
66
"os"
7-
"os/exec"
87
"runtime/debug"
98
"strings"
109
"syscall"
@@ -52,6 +51,7 @@ func build(p problem) {
5251
}
5352
}()
5453

54+
// windows用户注释这两行
5555
mask := syscall.Umask(0)
5656
defer syscall.Umask(mask)
5757

@@ -63,24 +63,29 @@ func build(p problem) {
6363

6464
log.Printf("开始创建 %d %s 的文件夹...\n", p.ID, p.Title)
6565

66+
content, fc := getGraphql(p)
67+
if fc == "" {
68+
log.Panicf("查无Go语言写法")
69+
}
70+
6671
// 利用 chrome 打开题目页面
67-
go func() {
68-
cmd := exec.Command("google-chrome", p.link())
69-
_, err = cmd.Output()
70-
if err != nil {
71-
panic(err.Error())
72-
}
73-
}()
72+
// go func() {
73+
// cmd := exec.Command("google-chrome", p.link())
74+
// _, err = cmd.Output()
75+
// if err != nil {
76+
// panic(err.Error())
77+
// }
78+
// }()
7479

75-
fc := getFunction(p.link())
80+
// fc := getFunction(p.link())
7681

77-
fcName, para, ans, fc := parseFunction(fc)
82+
fcName, para, ans, _ := parseFunction(fc)
7883

7984
creatGo(p, fc, ans)
8085

8186
creatGoTest(p, fcName, para, ans)
8287

83-
creatREADME(p)
88+
creatREADME(p, content)
8489

8590
log.Printf("%d.%s 的文件夹,创建完毕。\n", p.ID, p.Title)
8691
}

Helper/config.go

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ const (
1414
type config struct {
1515
Username string
1616
Password string
17+
Cookie string
1718

1819
// 以下是电子邮件设置
1920
SMTP string

Helper/leetcode-getGraphql.go

+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package main
2+
3+
import (
4+
"bytes"
5+
"encoding/json"
6+
"io/ioutil"
7+
"log"
8+
"net/http"
9+
)
10+
11+
type JsL4CodeSnippets []struct {
12+
Lang string
13+
Code string
14+
}
15+
16+
type JsL3Detail struct {
17+
Content string
18+
CodeSnippets JsL4CodeSnippets
19+
}
20+
21+
type JsL2Question struct {
22+
Question JsL3Detail
23+
}
24+
25+
type JsL1Data struct {
26+
Data JsL2Question
27+
}
28+
29+
func getGraphql(p problem) (string, string) {
30+
// req := newReq()
31+
32+
params := make(map[string]interface{})
33+
params["operationName"] = "questionData"
34+
params["query"] = "query questionData($titleSlug: String!) { question(titleSlug: $titleSlug) { content codeSnippets { lang code } } }"
35+
titleSlug := make(map[string]string)
36+
titleSlug["titleSlug"] = p.TitleSlug
37+
params["variables"] = titleSlug
38+
39+
// Make this JSON
40+
postJson, _ := json.Marshal(params)
41+
42+
// http.POST expects an io.Reader, which a byte buffer does
43+
postContent := bytes.NewBuffer(postJson)
44+
45+
resp, err := http.Post("https://leetcode.com/graphql", "application/json", postContent)
46+
if err != nil {
47+
log.Fatal("getGraphql: POST Error: " + err.Error())
48+
}
49+
50+
defer resp.Body.Close()
51+
52+
if resp.StatusCode != 200 {
53+
log.Fatal("抓题失败 code: " + resp.Status)
54+
}
55+
56+
respBytes, err := ioutil.ReadAll(resp.Body)
57+
if err != nil {
58+
log.Fatal("getGraphql: Read Error: " + err.Error())
59+
}
60+
61+
//byte数组直接转成string,优化内存
62+
// str := (*string)(unsafe.Pointer(&respBytes))
63+
// fmt.Printf("%#v\n", *str)
64+
65+
res := &JsL1Data{}
66+
json.Unmarshal(respBytes, &res)
67+
68+
code := ""
69+
for _, qc := range res.Data.Question.CodeSnippets {
70+
if qc.Lang == "Go" {
71+
code = qc.Code
72+
}
73+
}
74+
return res.Data.Question.Content, code
75+
}

Helper/problemGoFile.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import (
99
)
1010

1111
func parseFunction(fc string) (fcName, para, ansType, nfc string) {
12-
log.Println("准备分解函数:", fc)
12+
log.Println("正在分解函数")
1313

1414
defer func() { // 必须要先声明defer,否则不能捕获到panic异常
1515
if err := recover(); err != nil {

Helper/problemReadme.go

+7-3
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,24 @@ import (
44
"fmt"
55
"sort"
66
"strings"
7+
8+
"github.com/TruthHun/html2md"
79
)
810

9-
func creatREADME(p problem) {
11+
func creatREADME(p problem, s string) {
1012
fileFormat := `# [%d. %s](%s)
1113
1214
%s
1315
`
1416

1517
questionDescription := strings.TrimSpace(getDescription(p.link()))
1618

17-
content := fmt.Sprintf(fileFormat, p.ID, p.Title, p.link(), questionDescription)
19+
content := fmt.Sprintf(fileFormat, p.ID, p.Title, p.link(), questionDescription) + s + "\n\n## 解题思路\n\n## 可能的變化"
1820

1921
content = replaceCharacters(content)
2022

23+
content = html2md.Convert(content)
24+
2125
filename := fmt.Sprintf("%s/README.md", p.Dir())
2226

2327
write(filename, content)
@@ -36,7 +40,7 @@ func replaceCharacters(s string) string {
3640
"&lt;": "<",
3741
"&gt;": ">",
3842
"&ge;": ">=",
39-
"&nbsp;": "`",
43+
"&nbsp;": " ",
4044
"&amp;": "&",
4145
"&#39;": "'",
4246
" \n": "\n",

0 commit comments

Comments
 (0)