LeetCode 練習專案
這是一個用來紀錄與管理 LeetCode 練習的專案,整合 C# 與 Go 的題解、基本測試模板、月度學習日誌,以及一支小工具腳本,協助快速建立新題目與維持一致的結構與習慣。
專案架構
.
├── problems/ # 每題一個資料夾 (NNNN-kebab-case)
│ └── 3516-find-closest-person/
│ ├── README.md # 題目說明與解題筆記
│ ├── csharp/ # C# 解法 (dotnet)
│ ├── go/ # Go 解法 (go module)
│ └── test/ # C#/Go 測試模板與測試檔
├── utils/
│ ├── leetcode_helper.sh # 建題、更新 README、建立月誌
│ └── run_tests.sh # 全域測試執行器(選擇 C#/Go 或全部)
├── logs/ # 月度練習紀錄 (YYYY-MM.md)
├── templates/ # 檔案模板 (.tmpl)
│ ├── problem/ # 建題用模板(README、C#/Go、test)
│ ├── problem-template.md.tmpl # 題解寫作指引模板(參考用)
│ └── logs-template.md.tmpl # 月誌模板
├── legacy/ # 舊題或舊結構的紀錄
├── LICENSE
└── README.md
命名慣例:問題資料夾以「4 位數題號 + 題目英文 kebab-case」命名,例如 3025-find-the-number-of-ways-to-place-people-i
。
需求與環境
- C#: 安裝
.NET SDK 8+
,常用指令dotnet build / run / test
- Go: 安裝
Go 1.21+
,常用指令go build / run / test
- Bash: 可執行
utils/leetcode_helper.sh
與utils/run_tests.sh
初次使用請先授權腳本:
chmod +x utils/leetcode_helper.sh utils/run_tests.sh
常用操作
- 新增題目(自動建立資料夾、README、C#/Go 程式與測試模板)
./utils/leetcode_helper.sh problem <題號> <題目名稱-kebab> <難度>
# 範例
./utils/leetcode_helper.sh problem 1 two-sum Easy
./utils/leetcode_helper.sh problem 3000 maximum-area-rectangle Medium
# 顯示說明:
./utils/leetcode_helper.sh --help
建立完成後的結構(示意):
problems/NNNN-name/
├── README.md
├── csharp/
│ ├── Program.cs
│ └── csharp.csproj
├── go/
│ ├── main.go
│ └── go.mod
└── test/
├── SolutionTests.cs # xUnit 測試
├── TestProject.csproj
├── main_test.go # Go testing
└── edge_cases.md
- 建立月度日誌(依模板生成
logs/YYYY-MM.md
)
./utils/leetcode_helper.sh log 2025-09
- 更新主 README(目前顯示題目統計,後續可擴充自動彙整)
./utils/leetcode_helper.sh readme
執行與測試
- 執行 C# 解法:
cd problems/NNNN-name/csharp
dotnet run
- 執行 Go 解法:
cd problems/NNNN-name/go
go run main.go
- 執行該題的測試(同時跑 C# 與 Go):
./utils/run_tests.sh NNNN-name [all|csharp|go]
# 也可只給題號:
./utils/run_tests.sh 3025
# 僅跑 C# 或 Go:
./utils/run_tests.sh 3025 csharp
./utils/run_tests.sh 3025 go
# 顯示說明:
./utils/run_tests.sh --help
# 列出目前可用題目:
./utils/run_tests.sh --list
或分別執行:
cd problems/NNNN-name/test
dotnet test
go test -v
utils 的用途
utils/leetcode_helper.sh
提供三個主要功能,將繁瑣步驟自動化、保持專案一致性;utils/run_tests.sh
則統一執行測試。
- problem:根據輸入的題號、名稱與難度,建立一個完整題目骨架
- 產生題目
README.md
(含題目資訊、思路、測試與筆記段落) - 建立
csharp/
與go/
目錄及基本程式碼 - 建立
test/
目錄,內含 xUnit、Go 測試模板(統一用utils/run_tests.sh
執行) - 初始化 Go module(
go.mod
)
- 產生題目
- readme:掃描
problems/
題目數量,輸出簡單統計到終端(可再擴充寫回本檔) - log:依
templates/logs-template.md.tmpl
生成月誌雛形,方便每日記錄與月度回顧
utils/run_tests.sh
全域測試執行:
- 用法:
./utils/run_tests.sh <problem> [all|csharp|go]
- 可為題號(如
3025
)、資料夾名(如3025-find-...
)、或完整路徑(如problems/3025-...
) - 其他:
--help
顯示說明、--list
列出可用題目 - 範例:
./utils/run_tests.sh 3025
(同時跑 C# 與 Go)./utils/run_tests.sh 3025 csharp
(只跑 C#)./utils/run_tests.sh --list
小提醒:腳本內建的模板語言為繁中,可依需求修改 templates/
與腳本內容。
模板與筆記
- 題目模板:
templates/problem-template.md.tmpl
- 月誌模板:
templates/logs-template.md.tmpl
建議每題完成後:
- 更新該題
README.md
的「解題思路」「測試案例」「學習筆記」段落 - 在
logs/YYYY-MM.md
紀錄當日題目、時間、心得與統計
Templates 強化(重點)
- Problem 模板新增:
- 先備條件與限制(輸入範圍、是否需要 in-place/排序)
- 解法比較(A/B/C)、正確性要點、優缺點
- 乾跑(Dry Run)步驟示例
- API 設計(C#/Go 方法簽名)與常見陷阱清單
- 對拍/隨機測試建議;更完整的邊界清單
- Logs 模板新增:
- 本月設定(主題/目標/挑戰)與主題覆蓋追蹤
- 連續天數(Streak)與錯誤類型統計
- 困難案例復盤與下月計畫欄位
Problem 模板範例(節錄,3516)
# [3516] Find Closest Person
## 題目資訊
- 難度: Easy
- 標籤: Math
- 題目連結: https://leetcode.com/problems/find-closest-person/
- 練習日期: 2025-09-04
- 目標複雜度: 時間 O(1), 空間 O(1)
## 先備條件與限制
- 輸入: x, y, z 為整數;值域小;需比較兩者距離
- 回傳: 1/2/0 表示誰先到或同時到
## 解法比較
1. 解法A(直接比距離)
- 思路: 計算 |x-z| 與 |y-z|,比較大小
- 正確性: 距離等速 → 距離小者先到
- 複雜度: O(1) / O(1)
2. 解法B(無)
## 乾跑
- x=2, y=7, z=4 → |2-4|=2, |7-4|=3 → 回傳 1
## 實作細節與 API 設計
- C#
public int FindClosest(int x, int y, int z) { ... }
- Go
func findClosest(x, y, z int) int { ... }
## 測試案例
- 邊界: 等距(回傳0)、同點、極小/極大值
完整寫法可參考:problems/3516-find-closest-person/README.md
。
測試範例(可直接複製改題名)
- xUnit(C#)
using Xunit;
public class SolutionTests {
[Theory]
[InlineData(2, 7, 4, 1)]
[InlineData(2, 5, 6, 2)]
[InlineData(1, 5, 3, 0)]
public void FindClosest_Works(int x, int y, int z, int expected) {
var s = new Solution();
Assert.Equal(expected, s.FindClosest(x, y, z));
}
}
- Go testing
package main
import "testing"
func TestFindClosest(t *testing.T) {
tests := []struct{ x, y, z, want int }{
{2, 7, 4, 1},
{2, 5, 6, 2},
{1, 5, 3, 0},
}
for _, tt := range tests {
if got := findClosest(tt.x, tt.y, tt.z); got != tt.want {
t.Fatalf("x=%d y=%d z=%d want=%d got=%d", tt.x, tt.y, tt.z, tt.want, got)
}
}
}
自訂模板
- 直接編輯:
templates/problem-template.md.tmpl
、templates/logs-template.md.tmpl
- 工具腳本已改為讀取
templates/
目錄的檔案生成骨架:- 問題頁:
templates/problem/README.md.tmpl
- C#:
templates/problem/csharp/*
- Go:
templates/problem/go/*
- 測試:
templates/problem/test/*
- 月誌:
templates/logs-template.md.tmpl
不需修改腳本本身即可客製化模板。
- 問題頁:
工具清單
-
utils/leetcode_helper.sh
: 管理題目與月誌- 功能:
problem <題號> <題目名稱-kebab> <難度>
:建立新題目(產生README.md
、csharp/
、go/
、test/
骨架)log [YYYY-MM]
:建立月度學習日誌(預設本月)readme
:顯示題目數量統計-h|--help
:顯示說明
- 範例:
./utils/leetcode_helper.sh problem 3025 find-the-number-of-ways-to-place-people-i Medium
./utils/leetcode_helper.sh log 2025-09
./utils/leetcode_helper.sh --help
- 功能:
-
utils/run_tests.sh
: 執行指定題目的測試- 語法:
./utils/run_tests.sh <problem> [all|csharp|go]
- 可為:題號(如
3025
)/ 目錄名(如3025-find-…
)/ 完整路徑(如problems/3025-…
) - 參數:
--help
顯示說明、--list
列出現有題目 - 範例:
./utils/run_tests.sh 3025
(同時跑 C# 與 Go)./utils/run_tests.sh 3025 csharp
(只跑 C#)./utils/run_tests.sh --list
- 語法:
未來可擴充方向
- 主 README 自動彙整各題狀態(難度、語言、連結、完成度)
- 加入 CI(如 GitHub Actions)自動跑各題測試
- 更完整的模板與範例(含 I/O、邊界測資)
歡迎依個人習慣調整腳本與模板,持續穩定地練習最重要!
Languages
C#
66%
Go
19.4%
Shell
14%
Makefile
0.6%