Skip to content

Commit 53d0a36

Browse files
committed
remove pre/next in markdown
1 parent 5542b97 commit 53d0a36

842 files changed

Lines changed: 1230 additions & 5841 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/deploy.yml

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,16 @@ jobs:
5252
./website/public/ \
5353
"${SSH_USERNAME}@${SSH_HOST}:${SERVER_DESTINATION:-/var/www/books/leetcode/}"
5454
55-
word-count: # 重新统计总字数并把 README 里的徽章数字刷新、自动提交回仓库
55+
word-count: # 重新统计总字数,并通过 PR 刷新 README 里的徽章数字
5656
# 只在 master 上跑(add_hugo 等分支不自动改 README)。
57+
# master 是受保护分支(必须走 PR),所以这里不直接 push,而是开/更新一个 PR。
58+
# 需要在 Settings → Actions → General → Workflow permissions 勾选
59+
# "Allow GitHub Actions to create and approve pull requests"。
5760
if: github.ref == 'refs/heads/master'
5861
runs-on: ubuntu-latest
5962
permissions:
60-
contents: write # 需要写权限才能 commit & push 回仓库
63+
contents: write # 推送 PR 分支
64+
pull-requests: write # 创建/更新 PR
6165
steps:
6266
- uses: actions/checkout@v5
6367

@@ -72,19 +76,22 @@ jobs:
7276
echo "total word count = $COUNT"
7377
echo "count=$COUNT" >> "$GITHUB_OUTPUT"
7478
75-
- name: Update badge & commit if changed
79+
- name: Update badge number in README
7680
run: |
77-
# 只替换 README 里 Total Word Count 徽章的数字部分
78-
COUNT="${{ steps.wc.outputs.count }}"
79-
sed -i -E "s#(Total%20Word%20Count-)[0-9]+(-success)#\1${COUNT}\2#" README.md
80-
if git diff --quiet -- README.md; then
81-
echo "徽章已是最新(${COUNT}),无需提交。"
82-
else
83-
git config user.name "github-actions[bot]"
84-
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
85-
git add README.md
86-
# [skip ci]:这次只改 README 的自动提交不必再触发任何 workflow(deploy 已 paths-ignore,
87-
# 但 test.yml 没有,所以统一用 skip ci 防止多余构建,也彻底杜绝循环触发)。
88-
git commit -m "chore: update Total Word Count badge to ${COUNT} [skip ci]"
89-
git push
90-
fi
81+
sed -i -E "s#(Total%20Word%20Count-)[0-9]+(-success)#\1${{ steps.wc.outputs.count }}\2#" README.md
82+
83+
- name: Open/update PR if the badge changed
84+
# 仅当 README 真的变了才会建/更新 PR;固定分支名 chore/word-count-badge,
85+
# 始终复用同一个 PR,不会刷屏。合并即可更新徽章。
86+
uses: peter-evans/create-pull-request@v6
87+
with:
88+
add-paths: README.md
89+
branch: chore/word-count-badge
90+
delete-branch: true
91+
commit-message: "chore: update Total Word Count badge to ${{ steps.wc.outputs.count }}"
92+
title: "chore: update Total Word Count badge to ${{ steps.wc.outputs.count }}"
93+
body: |
94+
自动刷新 README 的 Total Word Count 徽章为 **${{ steps.wc.outputs.count }}**
95+
(口径:汉字 + 英文单词,已剔除代码块;由 `website/content/ChapterFour/pytool/WordCount.py` 统计)。
96+
97+
合并即可更新徽章;若数字没变化则不会创建本 PR。

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -488,7 +488,7 @@
488488
|0348|Design Tic-Tac-Toe||57.6%|Medium||
489489
|0349|Intersection of Two Arrays|[Go](https://github.com/halfrost/LeetCode-Go/tree/master/leetcode/0349.Intersection-of-Two-Arrays)|70.2%|Easy||
490490
|0350|Intersection of Two Arrays II|[Go](https://github.com/halfrost/LeetCode-Go/tree/master/leetcode/0350.Intersection-of-Two-Arrays-II)|55.5%|Easy||
491-
|0351|Android Unlock Patterns||51.3%|Medium||
491+
|0351|Android Unlock Patterns|[Go](https://github.com/halfrost/LeetCode-Go/tree/master/leetcode/0351.Android-Unlock-Patterns)|51.3%|Medium||
492492
|0352|Data Stream as Disjoint Intervals|[Go](https://github.com/halfrost/LeetCode-Go/tree/master/leetcode/0352.Data-Stream-as-Disjoint-Intervals)|51.5%|Hard||
493493
|0353|Design Snake Game||39.0%|Medium||
494494
|0354|Russian Doll Envelopes|[Go](https://github.com/halfrost/LeetCode-Go/tree/master/leetcode/0354.Russian-Doll-Envelopes)|38.3%|Hard||

ctl/label.go

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -123,16 +123,16 @@ func newDeletePreNext() *cobra.Command {
123123
}
124124

125125
func addPreNext() {
126-
// Chpater one add pre-next
127-
addPreNextLabel(chapterOneFileOrder, []string{}, []int{}, "", "ChapterOne", "ChapterTwo")
128-
// Chpater two add pre-next
129-
addPreNextLabel(chapterTwoFileOrder, chapterOneFileOrder, []int{}, "ChapterOne", "ChapterTwo", "ChapterThree")
130-
// Chpater three add pre-next
131-
addPreNextLabel(chapterThreeFileOrder, chapterTwoFileOrder, []int{}, "ChapterTwo", "ChapterThree", "ChapterFour")
132-
// Chpater four add pre-next
133-
//fmt.Printf("%v\n", getChapterFourFileOrder())
134-
chapterFourFileOrder, solutionIds := getChapterFourFileOrder()
135-
addPreNextLabel(chapterFourFileOrder, chapterThreeFileOrder, solutionIds, "ChapterThree", "ChapterFour", "")
126+
// 上/下页导航已改由 Hugo 主题在渲染时动态生成
127+
// (themes/book/layouts/partials/docs/inject/content-after.html),
128+
// 不再把导航 HTML 写进 markdown,避免与主题渲染的导航重复。
129+
// 如需恢复写入 markdown 的旧行为,取消下面的注释即可。
130+
//
131+
// addPreNextLabel(chapterOneFileOrder, []string{}, []int{}, "", "ChapterOne", "ChapterTwo")
132+
// addPreNextLabel(chapterTwoFileOrder, chapterOneFileOrder, []int{}, "ChapterOne", "ChapterTwo", "ChapterThree")
133+
// addPreNextLabel(chapterThreeFileOrder, chapterTwoFileOrder, []int{}, "ChapterTwo", "ChapterThree", "ChapterFour")
134+
// chapterFourFileOrder, solutionIds := getChapterFourFileOrder()
135+
// addPreNextLabel(chapterFourFileOrder, chapterThreeFileOrder, solutionIds, "ChapterThree", "ChapterFour", "")
136136
}
137137

138138
func addPreNextLabel(order, preOrder []string, chapterFourIds []int, preChapter, chapter, nextChapter string) {
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package leetcode
2+
3+
// blocker351[a][b] 记录从点 a 滑到点 b 必须先经过的中间点;0 表示两点相邻、无需经过中间点。
4+
// 例如 1->3 必须先经过 2,1->9 必须先经过 5。
5+
var blocker351 = [10][10]int{
6+
1: {3: 2, 7: 4, 9: 5},
7+
2: {8: 5},
8+
3: {1: 2, 7: 5, 9: 6},
9+
4: {6: 5},
10+
6: {4: 5},
11+
7: {1: 4, 3: 5, 9: 8},
12+
8: {2: 5},
13+
9: {1: 5, 3: 6, 7: 8},
14+
}
15+
16+
// 解法一 回溯。0 号点是虚拟起点,从它出发可以到任意一个数字。
17+
func numberOfPatterns(m int, n int) int {
18+
visited := make([]bool, 10)
19+
return countPatterns351(visited, 0, 0, m, n)
20+
}
21+
22+
// now 是当前所在的点,already 是已经选中的点数,统计长度落在 [m,n] 内的合法图案数。
23+
func countPatterns351(visited []bool, now, already, m, n int) int {
24+
res := 0
25+
if already >= m && already <= n {
26+
res++
27+
}
28+
if already >= n { // 已达到最大长度,无需再往下选
29+
return res
30+
}
31+
for next := 1; next <= 9; next++ {
32+
mid := blocker351[now][next]
33+
// next 没被用过,且 next 与 now 相邻(mid==0)或中间点已被划过(visited[mid])
34+
if !visited[next] && (mid == 0 || visited[mid]) {
35+
visited[next] = true
36+
res += countPatterns351(visited, next, already+1, m, n)
37+
visited[next] = false
38+
}
39+
}
40+
return res
41+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package leetcode
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
)
7+
8+
type question351 struct {
9+
para351
10+
ans351
11+
}
12+
13+
// para is the parameter
14+
// one represents the first parameter, two the second
15+
type para351 struct {
16+
one int
17+
two int
18+
}
19+
20+
// ans is the answer
21+
// one represents the first answer
22+
type ans351 struct {
23+
one int
24+
}
25+
26+
func Test_Problem351(t *testing.T) {
27+
28+
qs := []question351{
29+
30+
{
31+
para351{1, 1},
32+
ans351{9},
33+
},
34+
35+
{
36+
para351{1, 2},
37+
ans351{65},
38+
},
39+
40+
{
41+
para351{2, 3},
42+
ans351{376},
43+
},
44+
45+
{
46+
para351{4, 5},
47+
ans351{8776},
48+
},
49+
50+
{
51+
para351{4, 9},
52+
ans351{389112},
53+
},
54+
}
55+
56+
fmt.Printf("------------------------Leetcode Problem 351------------------------\n")
57+
58+
for _, q := range qs {
59+
a, p := q.ans351, q.para351
60+
got := numberOfPatterns(p.one, p.two)
61+
fmt.Printf("【input】:%v 【output】:%v\n", p, got)
62+
if got != a.one {
63+
t.Fatalf("input m=%v n=%v: expected %v, got %v", p.one, p.two, a.one, got)
64+
}
65+
}
66+
fmt.Printf("\n\n\n")
67+
}
Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,48 @@
11
package leetcode
22

3+
// 解法一 逐行把矩阵看成柱状图,对每一行求“柱状图中最大矩形”(第 84 题)。
4+
// 时间复杂度 O(m*n),空间复杂度 O(n)。
35
func maximalRectangle(matrix [][]byte) int {
4-
return 0
6+
if len(matrix) == 0 || len(matrix[0]) == 0 {
7+
return 0
8+
}
9+
n := len(matrix[0])
10+
heights, res := make([]int, n), 0
11+
for i := 0; i < len(matrix); i++ {
12+
for j := 0; j < n; j++ {
13+
if matrix[i][j] == '1' {
14+
heights[j]++
15+
} else {
16+
heights[j] = 0
17+
}
18+
}
19+
if area := largestRectangleArea85(heights); area > res {
20+
res = area
21+
}
22+
}
23+
return res
24+
}
25+
26+
// 单调栈求柱状图中的最大矩形面积。
27+
func largestRectangleArea85(heights []int) int {
28+
res, stack := 0, []int{}
29+
for i := 0; i <= len(heights); i++ {
30+
cur := 0
31+
if i < len(heights) {
32+
cur = heights[i]
33+
}
34+
for len(stack) > 0 && heights[stack[len(stack)-1]] >= cur {
35+
top := stack[len(stack)-1]
36+
stack = stack[:len(stack)-1]
37+
width := i
38+
if len(stack) > 0 {
39+
width = i - stack[len(stack)-1] - 1
40+
}
41+
if area := heights[top] * width; area > res {
42+
res = area
43+
}
44+
}
45+
stack = append(stack, i)
46+
}
47+
return res
548
}

leetcode/9990085.Maximal-Rectangle/85. Maximal Rectangle_test.go

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,37 @@ func Test_Problem85(t *testing.T) {
3030
para85{[][]byte{{'1', '0', '1', '0', '0'}, {'1', '0', '1', '1', '1'}, {'1', '1', '1', '1', '1'}, {'1', '0', '0', '1', '0'}}},
3131
ans85{6},
3232
},
33+
34+
{
35+
para85{[][]byte{}},
36+
ans85{0},
37+
},
38+
39+
{
40+
para85{[][]byte{{'0'}}},
41+
ans85{0},
42+
},
43+
44+
{
45+
para85{[][]byte{{'1'}}},
46+
ans85{1},
47+
},
48+
49+
{
50+
para85{[][]byte{{'1', '1'}, {'1', '1'}}},
51+
ans85{4},
52+
},
3353
}
3454

3555
fmt.Printf("------------------------Leetcode Problem 85------------------------\n")
3656

3757
for _, q := range qs {
38-
_, p := q.ans85, q.para85
39-
fmt.Printf("【input】:%v 【output】:%v\n", p, maximalRectangle(p.one))
58+
a, p := q.ans85, q.para85
59+
got := maximalRectangle(p.one)
60+
fmt.Printf("【input】:%v 【output】:%v\n", p, got)
61+
if got != a.one {
62+
t.Fatalf("input %v: expected %v, got %v", p.one, a.one, got)
63+
}
4064
}
4165
fmt.Printf("\n\n\n")
4266
}
Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,27 @@
11
package leetcode
22

3+
// 解法一 贪心 + 单调栈。每个字母只保留一个,结果在所有可行解中字典序最小。
4+
// 用 last 记录每个字母最后出现的下标;遍历时若当前字符比栈顶小,且栈顶字符后面还会
5+
// 再出现,就把栈顶弹出,从而让结果尽量小。时间复杂度 O(n),空间复杂度 O(1)(26 个字母)。
36
func removeDuplicateLetters(s string) string {
4-
return ""
7+
var last [26]int
8+
for i := 0; i < len(s); i++ {
9+
last[s[i]-'a'] = i
10+
}
11+
var inStack [26]bool
12+
stack := []byte{}
13+
for i := 0; i < len(s); i++ {
14+
c := s[i]
15+
if inStack[c-'a'] {
16+
continue
17+
}
18+
for len(stack) > 0 && stack[len(stack)-1] > c && last[stack[len(stack)-1]-'a'] > i {
19+
top := stack[len(stack)-1]
20+
stack = stack[:len(stack)-1]
21+
inStack[top-'a'] = false
22+
}
23+
stack = append(stack, c)
24+
inStack[c-'a'] = true
25+
}
26+
return string(stack)
527
}

leetcode/9990316.Remove-Duplicate-Letters/316. Remove Duplicate Letters_test.go

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,25 @@ func Test_Problem316(t *testing.T) {
3434
para316{"cbacdcbc"},
3535
ans316{"acdb"},
3636
},
37+
{
38+
para316{""},
39+
ans316{""},
40+
},
41+
{
42+
para316{"abcd"},
43+
ans316{"abcd"},
44+
},
3745
}
3846

3947
fmt.Printf("------------------------Leetcode Problem 316------------------------\n")
4048

4149
for _, q := range qs {
42-
_, p := q.ans316, q.para316
43-
fmt.Printf("【input】:%v 【output】:%v\n", p, removeDuplicateLetters(p.one))
50+
a, p := q.ans316, q.para316
51+
got := removeDuplicateLetters(p.one)
52+
fmt.Printf("【input】:%v 【output】:%v\n", p, got)
53+
if got != a.one {
54+
t.Fatalf("input %q: expected %q, got %q", p.one, a.one, got)
55+
}
4456
}
4557
fmt.Printf("\n\n\n")
4658
}

0 commit comments

Comments
 (0)