feat(utils, templates, docs): file-based templates + stronger README

This commit is contained in:
2025-09-12 09:44:30 +08:00
parent 002e9e6c32
commit d724a5fb65
35 changed files with 1421 additions and 727 deletions

296
README.md
View File

@@ -1,85 +1,247 @@
# LeetCode Practice Journey 🚀 # LeetCode 練習專案
## 📊 進度統計 這是一個用來紀錄與管理 LeetCode 練習的專案,整合 C# 與 Go 的題解、基本測試模板、月度學習日誌,以及一支小工具腳本,協助快速建立新題目與維持一致的結構與習慣。
- **總題數**: 0
- **已完成**: 0
- **開始日期**: 2025-09-01
- **最後更新**: 2025-09-01
### 難度分布 ## 專案架構
| 難度 | 完成數 | 總數 | 進度 |
|------|--------|------|------|
| Easy | 0 | 0 | 0% |
| Medium | 0 | 0 | 0% |
| Hard | 0 | 0 | 0% |
### 語言分布 ```
| 語言 | 完成題數 | .
|------|----------| ├── problems/ # 每題一個資料夾 (NNNN-kebab-case)
| C++ | 0 | │ └── 3516-find-closest-person/
| C# | 0 | │ ├── README.md # 題目說明與解題筆記
| Go | 0 | │ ├── csharp/ # C# 解法 (dotnet)
│ ├── go/ # Go 解法 (go module)
│ └── test/ # C#/Go 測試模板與腳本
├── utils/
│ └── leetcode_helper.sh # 建題、更新 README、建立月誌的工具腳本
├── logs/ # 月度練習紀錄 (YYYY-MM.md)
├── templates/ # 題目與月誌的 Markdown 範本
├── legacy/ # 舊題或舊結構的紀錄
├── LICENSE
└── README.md
```
## 🎯 學習目標 命名慣例問題資料夾以「4 位數題號 + 題目英文 kebab-case」命名例如 `3025-find-the-number-of-ways-to-place-people-i`
- [ ] 熟悉基本資料結構 (Array, LinkedList, Stack, Queue)
- [ ] 掌握雙指針技巧
- [ ] 動態規劃入門 (目標:完成 10 題)
- [ ] 樹和圖的遍歷
- [ ] 二分搜尋應用
## 📚 題目分類 ## 需求與環境
### Array & Hash Table - C#: 安裝 `.NET SDK 8+`,常用指令 `dotnet build / run / test`
| 題號 | 題目 | 難度 | 狀態 | 語言 | 筆記 | - Go: 安裝 `Go 1.21+`,常用指令 `go build / run / test`
|------|------|------|------|------|------| - Bash: 可執行 `utils/leetcode_helper.sh`
| 1 | [Two Sum](problems/0001-two-sum/) | Easy | ✅ | C#, Go | 經典入門題 |
| 15 | [3Sum](problems/0015-3sum/) | Medium | ✅ | C#, Go | 雙指針技巧 |
### Two Pointers 初次使用請先授權腳本:
| 題號 | 題目 | 難度 | 狀態 | 語言 | 筆記 |
|------|------|------|------|------|------|
| 11 | [Container With Most Water](problems/0011-container-with-most-water/) | Medium | ✅ | C# | 貪心思維 |
### String ```
| 題號 | 題目 | 難度 | 狀態 | 語言 | 筆記 | chmod +x utils/leetcode_helper.sh
|------|------|------|------|------|------| ```
| 3 | [Longest Substring Without Repeating Characters](problems/0003-longest-substring/) | Medium | 🔄 | C# | 滑動窗口 |
### Dynamic Programming ## 常用操作
| 題號 | 題目 | 難度 | 狀態 | 語言 | 筆記 |
|------|------|------|------|------|------|
| 70 | [Climbing Stairs](problems/0070-climbing-stairs/) | Easy | 📝 | - | 待開始 |
## 📅 月度學習記錄 - 新增題目自動建立資料夾、README、C#/Go 程式與測試模板)
- [2025年9月](logs/2025-09.md) - 基礎入門月 (完成 8 題)
- [2025年10月](logs/2025-09.md) - 進階提升月 (進行中...)
## 🧠 重點學習筆記 ```
./utils/leetcode_helper.sh problem <題號> <題目名稱-kebab> <難度>
### 常用模式總結 # 範例
1. **雙指針**: 適用於有序陣列的搜尋問題 ./utils/leetcode_helper.sh problem 1 two-sum Easy
2. **滑動窗口**: 子陣列/子字串的最佳化問題 ./utils/leetcode_helper.sh problem 3000 maximum-area-rectangle Medium
3. **Hash Map**: 快速查找和計數問題 ```
### 容易出錯的地方 建立完成後的結構(示意):
- 邊界條件檢查 (空陣列、單一元素)
- 整數溢位問題
- 陣列索引越界
## 📈 學習曲線反思 ```
- **第一週**: 熟悉基本語法和 LeetCode 平台 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
├── input1.txt / output1.txt
├── input2.txt / output2.txt
├── edge_cases.md
└── run_tests.sh # 一鍵執行 C# 與 Go 測試
```
## 🔗 有用資源 - 建立月度日誌(依模板生成 `logs/YYYY-MM.md`
- [LeetCode Patterns](https://leetcode.com/discuss/general-discussion/458695/dynamic-programming-patterns)
- [演算法與資料結構筆記](https://github.com/your-notes-repo) ```
- [LeetCode Solutions 參考](https://github.com/your-solutions-repo) ./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
```
cd problems/NNNN-name/test
./run_tests.sh
```
或分別執行:
```
cd problems/NNNN-name/test
dotnet test
go test -v
```
## utils 的用途
`utils/leetcode_helper.sh` 提供三個主要功能,將繁瑣步驟自動化、保持專案一致性:
- problem根據輸入的題號、名稱與難度建立一個完整題目骨架
- 產生題目 `README.md`(含題目資訊、思路、測試與筆記段落)
- 建立 `csharp/``go/` 目錄及基本程式碼
- 建立 `test/` 目錄,內含 xUnit、Go 測試模板與 `run_tests.sh`
- 初始化 Go module`go.mod`
- readme掃描 `problems/` 題目數量,輸出簡單統計到終端(可再擴充寫回本檔)
- log`templates/logs-template.md.tmpl` 生成月誌雛形,方便每日記錄與月度回顧
小提醒:腳本內建的模板語言為繁中,可依需求修改 `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`
## 測試範例(可直接複製改題名)
- xUnitC#
```csharp
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
```go
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`
不需修改腳本本身即可客製化模板。
## 未來可擴充方向
- 主 README 自動彙整各題狀態(難度、語言、連結、完成度)
- 加入 CI如 GitHub Actions自動跑各題測試
- 更完整的模板與範例(含 I/O、邊界測資
--- ---
*最後更新: 2025-09-01*
--- 歡迎依個人習慣調整腳本與模板,持續穩定地練習最重要!
account : iak64825@jioso.com
password : ww5&Hy73dgh

View File

@@ -1,586 +0,0 @@
# 1. 讓腳本可執行:
# chmod +x leetcode_helper.sh
# 2. 建立新題目:
# ./leetcode_helper.sh problem 1 two-sum Easy
# ./leetcode_helper.sh problem 3000 maximum-area-rectangle Medium
# 3. 建立月度日誌:
# ./leetcode_helper.sh log 2025-09
# 4. 更新README
# ./leetcode_helper.sh readme
#!/bin/bash
# 建立測試檔案
function create_test_files() {
local problem_dir="$1"
local number="$2"
local name="$3"
# 建立 C# 單元測試 (xUnit)
cat > "$problem_dir/test/SolutionTests.cs" << EOF
// LeetCode $number 單元測試
// 使用 xUnit 框架
using Xunit;
using System;
using System.Collections.Generic;
public class SolutionTests {
private readonly Solution _solution;
public SolutionTests() {
_solution = new Solution();
}
[Fact]
public void TestCase1() {
// Arrange
// TODO: 設定輸入資料
// var input = ;
// var expected = ;
// Act
// var result = _solution.YourMethod(input);
// Assert
// Assert.Equal(expected, result);
Assert.True(true); // 暫時通過,等待實作
}
[Fact]
public void TestCase2() {
// TODO: 第二個測試案例
Assert.True(true);
}
[Fact]
public void TestEdgeCases() {
// TODO: 邊界情況測試
// 空陣列、單一元素、最大值、最小值等
Assert.True(true);
}
}
EOF
# 建立 C# 測試專案檔
cat > "$problem_dir/test/TestProject.csproj" << EOF
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="../csharp/csharp.csproj" />
</ItemGroup>
</Project>
EOF
# 建立 Go 測試檔案
cat > "$problem_dir/test/main_test.go" << EOF
// LeetCode $number Go 單元測試
package main
import (
"testing"
"reflect"
)
func TestCase1(t *testing.T) {
// TODO: 設定測試資料
// input :=
// expected :=
// result := solve(input)
// if !reflect.DeepEqual(result, expected) {
// t.Errorf("TestCase1 failed. Expected: %v, Got: %v", expected, result)
// }
// 暫時通過測試
if false {
t.Errorf("請實作測試案例")
}
}
func TestCase2(t *testing.T) {
// TODO: 第二個測試案例
if false {
t.Errorf("請實作測試案例")
}
}
func TestEdgeCases(t *testing.T) {
// TODO: 邊界情況測試
if false {
t.Errorf("請實作邊界測試")
}
}
// 輔助函數:比較 slice
func equalSlices(a, b []int) bool {
if len(a) != len(b) {
return false
}
for i := range a {
if a[i] != b[i] {
return false
}
}
return true
}
EOF
# 建立測試資料檔案模板
cat > "$problem_dir/test/input1.txt" << EOF
# 測試案例 1 輸入
# TODO: 從 LeetCode 複製範例輸入
EOF
cat > "$problem_dir/test/output1.txt" << EOF
# 測試案例 1 期望輸出
# TODO: 從 LeetCode 複製範例輸出
EOF
cat > "$problem_dir/test/input2.txt" << EOF
# 測試案例 2 輸入
# TODO: 加入額外測試案例
EOF
cat > "$problem_dir/test/output2.txt" << EOF
# 測試案例 2 期望輸出
# TODO: 加入額外測試案例期望結果
EOF
cat > "$problem_dir/test/edge_cases.md" << EOF
# 邊界情況清單
## 需要測試的邊界情況
- [ ] 空輸入 (空陣列、空字串等)
- [ ] 單一元素
- [ ] 重複元素
- [ ] 最大值/最小值
- [ ] 負數情況
- [ ] 超大資料量
- [ ] 特殊字符 (如果是字串題目)
## 額外測試案例
### 案例 1:
**輸入**:
**輸出**:
**說明**:
### 案例 2:
**輸入**:
**輸出**:
**說明**:
EOF
# 建立測試執行腳本
cat > "$problem_dir/test/run_tests.sh" << 'EOF'
#!/bin/bash
echo "🧪 執行 LeetCode 題目測試"
echo "=========================="
# 執行 C# 測試
echo "📋 C# 測試結果:"
cd ../csharp
if dotnet build > /dev/null 2>&1; then
cd ../test
if dotnet test --logger "console;verbosity=minimal" 2>/dev/null; then
echo "✅ C# 測試通過"
else
echo "❌ C# 測試失敗"
fi
else
echo "❌ C# 編譯失敗"
fi
echo ""
# 執行 Go 測試
echo "📋 Go 測試結果:"
cd ../go
if go build > /dev/null 2>&1; then
cd ../test
if go test -v > /dev/null 2>&1; then
echo "✅ Go 測試通過"
else
echo "❌ Go 測試失敗"
echo "詳細輸出:"
go test -v
fi
else
echo "❌ Go 編譯失敗"
fi
echo ""
echo "📊 測試完成!"
EOF
chmod +x "$problem_dir/test/run_tests.sh"
}
# create_problem.sh - 建立新題目資料夾和檔案
function create_problem() {
local number="$1"
local name="$2"
local difficulty="$3"
if [[ -z "$number" || -z "$name" || -z "$difficulty" ]]; then
echo "使用方法: create_problem <題號> <題目名稱> <難度>"
echo "範例: create_problem 1 two-sum Easy"
exit 1
fi
# 格式化題號 (補零到4位數)
local formatted_number=$(printf "%04d" "$number")
local folder_name="${formatted_number}-${name}"
local problem_dir="problems/${folder_name}"
# 建立資料夾結構
mkdir -p "$problem_dir"
mkdir -p "$problem_dir/test"
# 建立 README.md
cat > "$problem_dir/README.md" << EOF
# [$number] $(echo "$name" | tr '-' ' ' | sed 's/\b\w/\u&/g')
## 題目資訊
- **難度**: $difficulty
- **標籤**:
- **題目連結**: [LeetCode](https://leetcode.com/problems/$name/)
- **練習日期**: $(date +%Y-%m-%d)
## 題目描述
>
## 解題思路
### 初步分析
- 這題主要考察什麼概念?
- 有什麼關鍵限制條件?
- 預期時間/空間複雜度?
### 解法概述
1. **暴力解法**:
- 思路:
- 時間複雜度O(?)
- 空間複雜度O(?)
2. **優化解法**:
- 思路:
- 時間複雜度O(?)
- 空間複雜度O(?)
## 實作細節
### C# 解法
\`\`\`csharp
// 核心程式碼片段或關鍵邏輯說明
\`\`\`
### Go 解法
\`\`\`go
// 核心程式碼片段或關鍵邏輯說明
\`\`\`
## 測試案例
### 範例輸入輸出
\`\`\`
Input:
Output:
Explanation:
\`\`\`
### 邊界情況
- [ ] 空陣列/空字串
- [ ] 單一元素
- [ ] 最大/最小值
- [ ] 重複元素
## 學習筆記
### 今天學到什麼?
-
### 遇到的困難
-
### 改善方向
-
### 相關題目
- [題目編號] 題目名稱 - 相似概念
- [題目編號] 題目名稱 - 進階版本
---
**總結**: 這題的核心概念是...,適合練習...技巧。
EOF
# 建立 C# 專案
mkdir -p "$problem_dir/csharp"
cd "$problem_dir/csharp"
dotnet new console --force > /dev/null 2>&1
# 覆寫自動生成的 Program.cs
cat > "Program.cs" << EOF
// LeetCode $number: $(echo "$name" | tr '-' ' ' | sed 's/\b\w/\u&/g')
// 難度: $difficulty
// 日期: $(date +%Y-%m-%d)
using System;
using System.Collections.Generic;
using System.Linq;
public class Solution {
public void Solve() {
// TODO: 實作解法
Console.WriteLine("Hello LeetCode $number!");
}
}
// 測試程式
public class Program {
public static void Main() {
Solution sol = new Solution();
sol.Solve();
// TODO: 加入測試案例
// TestCase1();
// TestCase2();
}
// 測試案例模板
/*
static void TestCase1() {
// Input:
// Expected:
// Actual:
Console.WriteLine("Test 1: ");
}
*/
}
EOF
cd - > /dev/null
# 建立 Go 解法檔案
mkdir -p "$problem_dir/go"
cat > "$problem_dir/go/main.go" << EOF
// LeetCode $number: $(echo "$name" | tr '-' ' ' | sed 's/\b\w/\u&/g')
// 難度: $difficulty
// 日期: $(date +%Y-%m-%d)
package main
import "fmt"
// TODO: 實作解法
func solve() {
fmt.Printf("Hello LeetCode %d!\n", $number)
}
// 測試程式
func main() {
solve()
// TODO: 加入測試案例
// testCase1()
// testCase2()
}
// 測試案例模板
/*
func testCase1() {
// Input:
// Expected:
// Actual:
fmt.Println("Test 1:")
}
*/
EOF
# 初始化 Go module
cd "$problem_dir/go"
go mod init "leetcode-$number" > /dev/null 2>&1
cd - > /dev/null
# 建立測試檔案
create_test_files "$problem_dir" "$number" "$name"
echo "✅ 已建立題目資料夾: $problem_dir"
echo "📁 檔案結構:"
echo "$problem_dir/"
echo "├── README.md"
echo "├── csharp/"
echo "│ ├── Program.cs"
echo "│ └── *.csproj"
echo "├── go/"
echo "│ ├── main.go"
echo "│ └── go.mod"
echo "└── test/"
echo " ├── SolutionTests.cs"
echo " ├── TestProject.csproj"
echo " ├── main_test.go"
echo " ├── input1.txt"
echo " ├── output1.txt"
echo " ├── input2.txt"
echo " ├── output2.txt"
echo " ├── edge_cases.md"
echo " └── run_tests.sh"
echo ""
echo "🚀 執行方式:"
echo "C#: cd $problem_dir/csharp && dotnet run"
echo "Go: cd $problem_dir/go && go run main.go"
echo "測試: cd $problem_dir/test && ./run_tests.sh"
}
# update_readme.sh - 更新主 README
function update_readme() {
echo "🔄 更新主 README.md..."
# 計算統計資料
local total_problems=$(find problems -maxdepth 1 -type d | wc -l)
total_problems=$((total_problems - 1)) # 排除 problems 資料夾本身
local completed_problems=$(find problems -name "README.md" -exec grep -l "✅" {} \; | wc -l)
echo "📊 發現 $total_problems 個題目,其中 $completed_problems 個已完成"
# 這裡可以加入更複雜的統計和README更新邏輯
# 暫時只顯示統計結果
}
# create_monthly_log.sh - 建立月度日誌
function create_monthly_log() {
local year_month="$1"
if [[ -z "$year_month" ]]; then
year_month=$(date +%Y-%m)
fi
local log_file="logs/${year_month}.md"
if [[ -f "$log_file" ]]; then
echo "⚠️ 月度日誌已存在: $log_file"
return 1
fi
mkdir -p logs
cat > "$log_file" << EOF
# ${year_month} 學習記錄
## 📅 每日練習記錄
### Week 1
| 日期 | 題目 | 難度 | 語言 | 耗時 | 狀態 | 心得 |
|------|------|------|------|------|------|------|
| | | | | | | |
### Week 2
| 日期 | 題目 | 難度 | 語言 | 耗時 | 狀態 | 心得 |
|------|------|------|------|------|------|------|
| | | | | | | |
### Week 3
| 日期 | 題目 | 難度 | 語言 | 耗時 | 狀態 | 心得 |
|------|------|------|------|------|------|------|
| | | | | | | |
### Week 4
| 日期 | 題目 | 難度 | 語言 | 耗時 | 狀態 | 心得 |
|------|------|------|------|------|------|------|
| | | | | | | |
## 📈 本月統計
### 完成情況
- **總練習天數**: 天
- **完成題數**: 題
- **語言分布**: C# (題), Go (題)
- **難度分布**: Easy (題), Medium (題), Hard (題)
### 時間投入
- **總時間**: 小時
- **平均每題**: 分鐘
- **每日平均**: 分鐘
## 🎯 本月重點學習
### 新掌握的技巧
1.
### 常犯錯誤分析
1.
### 語言學習心得
- **C#**:
- **Go**:
## 🔄 遇到的困難與解決
### 困難1:
- **問題**:
- **解決**:
- **學習**:
## 📝 改進計畫
### 下月目標
1.
### 學習方法調整
1.
## 💡 本月金句
>
---
**總結**:
EOF
echo "✅ 已建立月度日誌: $log_file"
}
# 主程式
case "$1" in
"problem")
create_problem "$2" "$3" "$4"
;;
"readme")
update_readme
;;
"log")
create_monthly_log "$2"
;;
*)
echo "LeetCode Practice Helper"
echo ""
echo "使用方法:"
echo " $0 problem <題號> <題目名稱> <難度> # 建立新題目"
echo " $0 readme # 更新主README"
echo " $0 log [年月] # 建立月度日誌"
echo ""
echo "範例:"
echo " $0 problem 1 two-sum Easy"
echo " $0 problem 15 3sum Medium"
echo " $0 log 2025-09"
;;
esac

View File

@@ -83,4 +83,102 @@
> "演算法不是背出來的,是理解出來的" - 在第15題3Sum卡住兩天後的感悟 > "演算法不是背出來的,是理解出來的" - 在第15題3Sum卡住兩天後的感悟
--- ---
**總結**: 八月是很好的開始,從完全新手到能獨立解決中等題目。九月要持續挑戰自己! **總結**: 八月是很好的開始,從完全新手到能獨立解決中等題目。九月要持續挑戰自己!
# YYYY年M月 學習記錄
## 本月設定(目標與主題)
- **主題**:例如 雙指針 / 滑動視窗 / DP / 圖論
- **目標題數**X 題Easy Y / Medium Z / Hard W
- **投入時間**:每日 ≥ N 分鐘;每週 ≥ M 小時
- **挑戰**:至少完成 Hard ≥ H 題;每週寫 1 篇總結
## 📅 每日練習記錄
### Week 1 (YYYY-MM-DD ~ YYYY-MM-DD)
| 日期 | 題目 | 難度 | 語言 | 耗時 | 狀態 | 心得 |
|------|------|------|------|------|------|------|
| | | | | | | |
### Week 2 (YYYY-MM-DD ~ YYYY-MM-DD)
| 日期 | 題目 | 難度 | 語言 | 耗時 | 狀態 | 心得 |
|------|------|------|------|------|------|------|
| | | | | | | |
### Week 3 (YYYY-MM-DD ~ YYYY-MM-DD)
| 日期 | 題目 | 難度 | 語言 | 耗時 | 狀態 | 心得 |
|------|------|------|------|------|------|------|
| | | | | | | |
### Week 4 (YYYY-MM-DD ~ YYYY-MM-DD)
| 日期 | 題目 | 難度 | 語言 | 耗時 | 狀態 | 心得 |
|------|------|------|------|------|------|------|
| | | | | | | |
## 🧭 主題覆蓋追蹤(勾選)
- [ ] 陣列/字串Two Pointers / Sliding Window
- [ ] 資料結構Stack/Queue/Heap/Set/Map
- [ ] 排序與搜尋Sorting / Binary Search
- [ ] 數學與位運算Math / Bit
- [ ] 動態規劃DP
- [ ] 圖論BFS/DFS/最短路/拓撲)
- [ ] 樹BST/遍歷/序列化)
## 📈 本月統計
### 完成情況
- **練習天數**: 天
- **完成題數**: 題Easy / Medium / Hard
- **語言分布**: C# (題), Go (題)
- **連續天數Streak**: 天;本月斷點:第 天
### 時間投入
- **總時間**: 小時
- **平均每題**: 分鐘
- **每日平均**: 分鐘
### 正確率 / 嘗試次數
- **一次通過**: 題
- **二次通過**: 題
- **多次調整**: 題(記錄主因:邊界/複雜度/實作)
## 🎯 本月重點學習
### 新掌握的技巧(至少 3 條)
1.
2.
3.
### 常見錯誤與對策
1. 錯誤:;對策:
2. 錯誤:;對策:
3. 錯誤:;對策:
### 語言心得(實作層面)
- **C#**LINQ/Span/效能注意點/測試習慣
- **Go**slice/map/指標/錯誤處理/benchmark 習慣
## 🔄 困難案例復盤
### 案例1題號/主題
- 問題:
- 嘗試:
- 解決:
- 學習:
### 案例2題號/主題
- 問題:
- 嘗試:
- 解決:
- 學習:
## 📝 下月計畫
- **目標題數**
- **重點主題**
- **練習節奏**
- **要避免的坑**
## 💡 本月金句
>
---
**總結**:本月最大收穫是 ______,接下來專注 ______

99
logs/2025-11.md Normal file
View File

@@ -0,0 +1,99 @@
# YYYY年M月 學習記錄
## 本月設定(目標與主題)
- 主題:雙指針 / 滑動視窗 / DP / 圖論(自訂)
- 目標題數X 題Easy Y / Medium Z / Hard W
- 投入時間:每日 ≥ N 分鐘;每週 ≥ M 小時
- 挑戰:至少完成 Hard ≥ H 題;每週寫 1 篇總結
## 📅 每日練習記錄
### Week 1 (YYYY-MM-DD ~ YYYY-MM-DD)
| 日期 | 題目 | 難度 | 語言 | 耗時 | 狀態 | 心得 |
|------|------|------|------|------|------|------|
| | | | | | | |
### Week 2 (YYYY-MM-DD ~ YYYY-MM-DD)
| 日期 | 題目 | 難度 | 語言 | 耗時 | 狀態 | 心得 |
|------|------|------|------|------|------|------|
| | | | | | | |
### Week 3 (YYYY-MM-DD ~ YYYY-MM-DD)
| 日期 | 題目 | 難度 | 語言 | 耗時 | 狀態 | 心得 |
|------|------|------|------|------|------|------|
| | | | | | | |
### Week 4 (YYYY-MM-DD ~ YYYY-MM-DD)
| 日期 | 題目 | 難度 | 語言 | 耗時 | 狀態 | 心得 |
|------|------|------|------|------|------|------|
| | | | | | | |
## 🧭 主題覆蓋追蹤(勾選)
- [ ] 陣列/字串Two Pointers / Sliding Window
- [ ] 資料結構Stack/Queue/Heap/Set/Map
- [ ] 排序與搜尋Sorting / Binary Search
- [ ] 數學與位運算Math / Bit
- [ ] 動態規劃DP
- [ ] 圖論BFS/DFS/最短路/拓撲)
- [ ]BST/遍歷/序列化)
## 📈 本月統計
### 完成情況
- 練習天數:天
- 完成題數Easy / Medium / Hard
- 語言分布C# (題), Go (題)
- 連續天數Streak本月斷點第 天
### 時間投入
- 總時間:小時
- 平均每題:分鐘
- 每日平均:分鐘
### 正確率 / 嘗試次數
- 一次通過:題
- 二次通過:題
- 多次調整:題(主因:邊界/複雜度/實作)
## 🎯 本月重點學習
### 新掌握的技巧(至少 3 條)
1.
2.
3.
### 常見錯誤與對策
1. 錯誤:;對策:
2. 錯誤:;對策:
3. 錯誤:;對策:
### 語言心得(實作層面)
- C#LINQ/Span/效能注意點/測試習慣
- Goslice/map/指標/錯誤處理/benchmark 習慣
## 🔄 困難案例復盤
### 案例1題號/主題
- 問題:
- 嘗試:
- 解決:
- 學習:
### 案例2題號/主題
- 問題:
- 嘗試:
- 解決:
- 學習:
## 📝 下月計畫
- 目標題數:
- 重點主題:
- 練習節奏:
- 要避免的坑:
## 💡 本月金句
>
---
**總結**:本月最大收穫是 ______,接下來專注 ______

99
logs/2025-12.md Normal file
View File

@@ -0,0 +1,99 @@
# YYYY年M月 學習記錄
## 本月設定(目標與主題)
- 主題:雙指針 / 滑動視窗 / DP / 圖論(自訂)
- 目標題數X 題Easy Y / Medium Z / Hard W
- 投入時間:每日 ≥ N 分鐘;每週 ≥ M 小時
- 挑戰:至少完成 Hard ≥ H 題;每週寫 1 篇總結
## 📅 每日練習記錄
### Week 1 (YYYY-MM-DD ~ YYYY-MM-DD)
| 日期 | 題目 | 難度 | 語言 | 耗時 | 狀態 | 心得 |
|------|------|------|------|------|------|------|
| | | | | | | |
### Week 2 (YYYY-MM-DD ~ YYYY-MM-DD)
| 日期 | 題目 | 難度 | 語言 | 耗時 | 狀態 | 心得 |
|------|------|------|------|------|------|------|
| | | | | | | |
### Week 3 (YYYY-MM-DD ~ YYYY-MM-DD)
| 日期 | 題目 | 難度 | 語言 | 耗時 | 狀態 | 心得 |
|------|------|------|------|------|------|------|
| | | | | | | |
### Week 4 (YYYY-MM-DD ~ YYYY-MM-DD)
| 日期 | 題目 | 難度 | 語言 | 耗時 | 狀態 | 心得 |
|------|------|------|------|------|------|------|
| | | | | | | |
## 🧭 主題覆蓋追蹤(勾選)
- [ ] 陣列/字串Two Pointers / Sliding Window
- [ ] 資料結構Stack/Queue/Heap/Set/Map
- [ ] 排序與搜尋Sorting / Binary Search
- [ ] 數學與位運算Math / Bit
- [ ] 動態規劃DP
- [ ] 圖論BFS/DFS/最短路/拓撲)
- [ ]BST/遍歷/序列化)
## 📈 本月統計
### 完成情況
- 練習天數:天
- 完成題數Easy / Medium / Hard
- 語言分布C# (題), Go (題)
- 連續天數Streak本月斷點第 天
### 時間投入
- 總時間:小時
- 平均每題:分鐘
- 每日平均:分鐘
### 正確率 / 嘗試次數
- 一次通過:題
- 二次通過:題
- 多次調整:題(主因:邊界/複雜度/實作)
## 🎯 本月重點學習
### 新掌握的技巧(至少 3 條)
1.
2.
3.
### 常見錯誤與對策
1. 錯誤:;對策:
2. 錯誤:;對策:
3. 錯誤:;對策:
### 語言心得(實作層面)
- C#LINQ/Span/效能注意點/測試習慣
- Goslice/map/指標/錯誤處理/benchmark 習慣
## 🔄 困難案例復盤
### 案例1題號/主題
- 問題:
- 嘗試:
- 解決:
- 學習:
### 案例2題號/主題
- 問題:
- 嘗試:
- 解決:
- 學習:
## 📝 下月計畫
- 目標題數:
- 重點主題:
- 練習節奏:
- 要避免的坑:
## 💡 本月金句
>
---
**總結**:本月最大收穫是 ______,接下來專注 ______

View File

@@ -0,0 +1,91 @@
# [42] Answer To Everything
## 題目資訊
- **難度**: Easy
- **標籤**:
- **題目連結**: https://leetcode.com/problems/answer-to-everything/
- **練習日期**: 2025-09-12
- **目標複雜度**: 時間 O(?)、空間 O(?)
## 題目描述
> 在這裡貼上題目的完整描述(或重點)
## 先備條件與限制
- 輸入限制n ∈ [?, ?]、值域 ∈ [?, ?]
- 回傳/輸出格式:...
- 其他:是否允許排序/就地修改
## 解題思路
### 初步分析
- 類型:雙指針 / 滑動視窗 / 排序 / DP / 貪心 / 圖論 ...
- 關鍵觀察:
- 複雜度目標理由:
### 解法比較
1. 解法A基準/暴力):
- 思路:
- 正確性:
- 複雜度O(?) / O(?)
2. 解法B優化
- 思路:
- 正確性:
- 複雜度O(?) / O(?)
### 乾跑Dry Run
- 範例:...
## 實作細節與 API 設計
### C# 方法簽名(示意)
```csharp
public class Solution {
// TODO: 根據題意調整簽名
public int Solve(int[] nums) {
return 0;
}
}
```
### Go 方法簽名(示意)
```go
func solve(nums []int) int {
return 0
}
```
### 常見陷阱
- 邊界:空/單一/極值/全相等
- 去重:排序後跳重複、集合
- 溢位:使用 64-bit
## 測試案例
### 範例輸入輸出
```
Input: ...
Output: ...
Explanation: ...
```
### 邊界清單
- [ ] 空陣列/空字串
- [ ] 單一元素 / 全相同
- [ ] 含負數/0/大數
- [ ] 去重
- [ ] 大資料壓力
## 複雜度分析
- 最壞:時間 O(?)、空間 O(?)
## 相關題目 / Follow-up
-
## 學習筆記
- 今天學到:
- 卡住與修正:
- 待優化:
---
**總結**:這題的核心在於 ______,適合練習 ______

View File

@@ -0,0 +1,24 @@
// LeetCode 42: Answer To Everything
// 難度: Easy
// 日期: 2025-09-12
using System;
using System.Collections.Generic;
using System.Linq;
public class Solution {
// TODO: 根據題意調整簽名
public int Solve(int[] nums) {
// 實作解法
return 0;
}
}
public class Program {
public static void Main() {
var s = new Solution();
// TODO: 可加入簡單輸入/輸出測試
Console.WriteLine("Hello LeetCode 42!");
}
}

View File

@@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,18 @@
// LeetCode 42: Answer To Everything
// 難度: Easy
// 日期: 2025-09-12
package main
import "fmt"
// TODO: 根據題意調整簽名
func solve(nums []int) int {
return 0
}
func main() {
fmt.Printf("Hello LeetCode 42!\n")
// TODO: 可加入簡單測試
}

View File

@@ -0,0 +1,24 @@
// LeetCode 42 單元測試xUnit
using Xunit;
public class SolutionTests {
private readonly Solution _s = new Solution();
[Fact]
public void Example1() {
// TODO: Arrange
// var input = new int[] { };
// var expected = 0;
// Act
// var got = _s.Solve(input);
// Assert.Equal(expected, got);
Assert.True(true);
}
[Fact]
public void EdgeCases() {
Assert.True(true);
}
}

View File

@@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="../csharp/csharp.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,20 @@
# 邊界情況清單42 Answer To Everything
## 需要測試的邊界
- [ ] 空輸入 / 單一元素
- [ ] 重複元素 / 全相同
- [ ] 極值(最小/最大)
- [ ] 含負數 / 0 / 大數
- [ ] 大資料量(接近上限)
## 額外案例
### 案例 1
- 輸入:
- 預期:
- 說明:
### 案例 2
- 輸入:
- 預期:
- 說明:

View File

@@ -0,0 +1,2 @@
# 測試案例 1 輸入42 Answer To Everything

View File

@@ -0,0 +1,2 @@
# 測試案例 2 輸入42 Answer To Everything

View File

@@ -0,0 +1,12 @@
// LeetCode 42 單元測試Go testing
package main
import "testing"
func TestExample(t *testing.T) {
// TODO: input := []int{}
// got := solve(input)
// want := 0
// if got != want { t.Fatalf("want %v got %v", want, got) }
}

View File

@@ -0,0 +1,2 @@
# 測試案例 1 期望輸出42 Answer To Everything

View File

@@ -0,0 +1,2 @@
# 測試案例 2 期望輸出42 Answer To Everything

View File

@@ -0,0 +1,36 @@
#!/bin/bash
set -e
echo "🧪 執行測試: 0042-answer-to-everything"
echo "=========================="
pushd "$(dirname "$0")" >/dev/null
echo "📋 C# 測試結果:"
if (cd ../csharp && dotnet build >/dev/null 2>&1); then
if dotnet test --logger "console;verbosity=minimal" >/dev/null 2>&1; then
echo "✅ C# 測試通過"
else
echo "❌ C# 測試失敗"
fi
else
echo "❌ C# 編譯失敗"
fi
echo ""
echo "📋 Go 測試結果:"
if (cd ../go && go build >/dev/null 2>&1); then
if go test -v >/dev/null 2>&1; then
echo "✅ Go 測試通過"
else
echo "❌ Go 測試失敗(顯示詳細)"
go test -v
fi
else
echo "❌ Go 編譯失敗"
fi
popd >/dev/null
echo ""
echo "📊 測試完成!"

View File

@@ -0,0 +1,99 @@
# YYYY年M月 學習記錄
## 本月設定(目標與主題)
- 主題:雙指針 / 滑動視窗 / DP / 圖論(自訂)
- 目標題數X 題Easy Y / Medium Z / Hard W
- 投入時間:每日 ≥ N 分鐘;每週 ≥ M 小時
- 挑戰:至少完成 Hard ≥ H 題;每週寫 1 篇總結
## 📅 每日練習記錄
### Week 1 (YYYY-MM-DD ~ YYYY-MM-DD)
| 日期 | 題目 | 難度 | 語言 | 耗時 | 狀態 | 心得 |
|------|------|------|------|------|------|------|
| | | | | | | |
### Week 2 (YYYY-MM-DD ~ YYYY-MM-DD)
| 日期 | 題目 | 難度 | 語言 | 耗時 | 狀態 | 心得 |
|------|------|------|------|------|------|------|
| | | | | | | |
### Week 3 (YYYY-MM-DD ~ YYYY-MM-DD)
| 日期 | 題目 | 難度 | 語言 | 耗時 | 狀態 | 心得 |
|------|------|------|------|------|------|------|
| | | | | | | |
### Week 4 (YYYY-MM-DD ~ YYYY-MM-DD)
| 日期 | 題目 | 難度 | 語言 | 耗時 | 狀態 | 心得 |
|------|------|------|------|------|------|------|
| | | | | | | |
## 🧭 主題覆蓋追蹤(勾選)
- [ ] 陣列/字串Two Pointers / Sliding Window
- [ ] 資料結構Stack/Queue/Heap/Set/Map
- [ ] 排序與搜尋Sorting / Binary Search
- [ ] 數學與位運算Math / Bit
- [ ] 動態規劃DP
- [ ] 圖論BFS/DFS/最短路/拓撲)
- [ ] 樹BST/遍歷/序列化)
## 📈 本月統計
### 完成情況
- 練習天數:天
- 完成題數Easy / Medium / Hard
- 語言分布C# (題), Go (題)
- 連續天數Streak本月斷點第 天
### 時間投入
- 總時間:小時
- 平均每題:分鐘
- 每日平均:分鐘
### 正確率 / 嘗試次數
- 一次通過:題
- 二次通過:題
- 多次調整:題(主因:邊界/複雜度/實作)
## 🎯 本月重點學習
### 新掌握的技巧(至少 3 條)
1.
2.
3.
### 常見錯誤與對策
1. 錯誤:;對策:
2. 錯誤:;對策:
3. 錯誤:;對策:
### 語言心得(實作層面)
- C#LINQ/Span/效能注意點/測試習慣
- Goslice/map/指標/錯誤處理/benchmark 習慣
## 🔄 困難案例復盤
### 案例1題號/主題
- 問題:
- 嘗試:
- 解決:
- 學習:
### 案例2題號/主題
- 問題:
- 嘗試:
- 解決:
- 學習:
## 📝 下月計畫
- 目標題數:
- 重點主題:
- 練習節奏:
- 要避免的坑:
## 💡 本月金句
>
---
**總結**:本月最大收穫是 ______接下來專注 ______。

View File

@@ -1,73 +0,0 @@
# [題目編號] 題目名稱
## 題目資訊
- **難度**: Easy/Medium/Hard
- **標籤**: Array, Hash Table, Two Pointers, etc.
- **題目連結**: [LeetCode](https://leetcode.com/problems/xxx/)
- **練習日期**: YYYY-MM-DD
## 題目描述
> 在這裡貼上題目的完整描述
## 解題思路
### 初步分析
- 這題主要考察什麼概念?
- 有什麼關鍵限制條件?
- 預期時間/空間複雜度?
### 解法概述
1. **暴力解法**:
- 思路:
- 時間複雜度O(?)
- 空間複雜度O(?)
2. **優化解法**:
- 思路:
- 時間複雜度O(?)
- 空間複雜度O(?)
## 實作細節
### C# 解法
```csharp
// 核心程式碼片段或關鍵邏輯說明
```
### Go 解法
```go
// 核心程式碼片段或關鍵邏輯說明
```
## 測試案例
### 範例輸入輸出
```
Input:
Output:
Explanation:
```
### 邊界情況
- [ ] 空陣列/空字串
- [ ] 單一元素
- [ ] 最大/最小值
- [ ] 重複元素
## 學習筆記
### 今天學到什麼?
-
### 遇到的困難
-
### 改善方向
-
### 相關題目
- [題目編號] 題目名稱 - 相似概念
- [題目編號] 題目名稱 - 進階版本
---
**總結**: 這題的核心概念是...,適合練習...技巧。

View File

@@ -0,0 +1,105 @@
# [題目編號] 題目名稱
## 題目資訊
- **難度**: Easy/Medium/Hard
- **標籤**: Array, Hash Table, Two Pointers, Sliding Window, Greedy, DP, Graph, Tree, Math, etc.
- **題目連結**: [LeetCode](https://leetcode.com/problems/xxx/)
- **練習日期**: YYYY-MM-DD
- **目標複雜度**: 時間 O(?), 空間 O(?)
## 題目描述
> 在這裡貼上題目的完整描述(或摘要)
## 先備條件與限制
- 輸入限制n ∈ [?, ?]、值域 ∈ [?, ?]、是否有重複、是否有負數/零
- 回傳/輸出格式:...
- 其他排序是否允許改變輸入、是否需穩定、是否需就地in-place
## 解題思路
### 初步分析(快速定位問題類型)
- 問題類型:如 雙指針 / 滑動視窗 / 排序 + 掃描 / 貪心 / DP / 單調結構 / 前綴和 / 二分 / 位運算 ...
- 關鍵觀察:列出 2-4 點(不等式關係、單調性、區間性質、可分解性)
- 目標複雜度理由:為什麼 O(n) 或 O(n log n) 足夠/必要?
### 解法比較
1. **解法 A基準/暴力/直接枚舉)**
- 思路:步驟 1-2-3
- 正確性:為什麼不會漏/不會重?
- 複雜度:時間 O(?)、空間 O(?)
- 優缺點:易寫/慢;好理解/不通過大資料
2. **解法 B優化排序/雙指針/結構)**
- 思路:步驟 1-2-3指出與解法 A 最大差異)
- 正確性:單調性/貪心選擇/狀態定義 的論證要點
- 複雜度:時間 O(?)、空間 O(?)
- 優缺點:通過大資料/實作較複雜;可讀性需注意
3. (可選)**解法 C進一步優化/其他路線)**
- 思路、正確性、複雜度、優缺點
### 乾跑Dry Run
使用一組小範例逐步展示索引/指標/狀態如何變化(建議附上 3-5 步驟)。
## 實作細節與 API 設計
### C# 方法簽名
```csharp
public class Solution {
// TODO: 根據題意調整簽名
public int Solve(int[] nums) {
// ...
}
}
```
### Go 方法簽名
```go
// TODO: 根據題意調整簽名
func solve(nums []int) int {
// ...
}
```
### 實作要點 / 常見陷阱
- 邊界空集合、單元素、全相等、極值INT_MIN/INT_MAX
- 去重:排序後跳重複、集合/哈希去重
- 早停:提早終止條件(例如 window 擴不動就停)
- 精度/溢位除法、乘法、64 位整數
## 測試案例
### 範例輸入輸出
```
Input: ...
Output: ...
Explanation: ...
```
### 邊界與特殊情況清單
- [ ] 空陣列/空字串
- [ ] 單一元素 / 全相同 / 全遞增 / 全遞減
- [ ] 含負數 / 含 0 / 大數
- [ ] 有重複值 / 需去重
- [ ] 大資料壓力測試n 接近上限)
### 對拍/隨機測試(可選)
- 與暴力解法對拍 1000 次;隨機生成測資,確保輸出一致
## 複雜度分析
- 最壞:時間 O(?)、空間 O(?)
- 平均:時間 O(?)
- 最佳:時間 O(?)(若有)
## 相關題目與 Follow-up
- [題目編號] 題目名稱(相同套路)
- Follow-up若輸入動態變化/資料流版本/線上查詢如何處理?
## 學習筆記
- 今天學到:
- 卡住點與修正:
- 下次優化想法:
---
**總結**:這題的核心在於 ______適合練習 ______ 技巧。

View File

@@ -0,0 +1,91 @@
# [{{NUMBER}}] {{NAME_TITLE}}
## 題目資訊
- **難度**: {{DIFFICULTY}}
- **標籤**:
- **題目連結**: https://leetcode.com/problems/{{NAME_SLUG}}/
- **練習日期**: {{DATE}}
- **目標複雜度**: 時間 O(?)、空間 O(?)
## 題目描述
> 在這裡貼上題目的完整描述(或重點)
## 先備條件與限制
- 輸入限制n ∈ [?, ?]、值域 ∈ [?, ?]
- 回傳/輸出格式:...
- 其他:是否允許排序/就地修改
## 解題思路
### 初步分析
- 類型:雙指針 / 滑動視窗 / 排序 / DP / 貪心 / 圖論 ...
- 關鍵觀察:
- 複雜度目標理由:
### 解法比較
1. 解法A基準/暴力):
- 思路:
- 正確性:
- 複雜度O(?) / O(?)
2. 解法B優化
- 思路:
- 正確性:
- 複雜度O(?) / O(?)
### 乾跑Dry Run
- 範例:...
## 實作細節與 API 設計
### C# 方法簽名(示意)
```csharp
public class Solution {
// TODO: 根據題意調整簽名
public int Solve(int[] nums) {
return 0;
}
}
```
### Go 方法簽名(示意)
```go
func solve(nums []int) int {
return 0
}
```
### 常見陷阱
- 邊界:空/單一/極值/全相等
- 去重:排序後跳重複、集合
- 溢位:使用 64-bit
## 測試案例
### 範例輸入輸出
```
Input: ...
Output: ...
Explanation: ...
```
### 邊界清單
- [ ] 空陣列/空字串
- [ ] 單一元素 / 全相同
- [ ] 含負數/0/大數
- [ ] 去重
- [ ] 大資料壓力
## 複雜度分析
- 最壞:時間 O(?)、空間 O(?)
## 相關題目 / Follow-up
-
## 學習筆記
- 今天學到:
- 卡住與修正:
- 待優化:
---
**總結**:這題的核心在於 ______適合練習 ______。

View File

@@ -0,0 +1,24 @@
// LeetCode {{NUMBER}}: {{NAME_TITLE}}
// 難度: {{DIFFICULTY}}
// 日期: {{DATE}}
using System;
using System.Collections.Generic;
using System.Linq;
public class Solution {
// TODO: 根據題意調整簽名
public int Solve(int[] nums) {
// 實作解法
return 0;
}
}
public class Program {
public static void Main() {
var s = new Solution();
// TODO: 可加入簡單輸入/輸出測試
Console.WriteLine("Hello LeetCode {{NUMBER}}!");
}
}

View File

@@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,18 @@
// LeetCode {{NUMBER}}: {{NAME_TITLE}}
// 難度: {{DIFFICULTY}}
// 日期: {{DATE}}
package main
import "fmt"
// TODO: 根據題意調整簽名
func solve(nums []int) int {
return 0
}
func main() {
fmt.Printf("Hello LeetCode {{NUMBER}}!\n")
// TODO: 可加入簡單測試
}

View File

@@ -0,0 +1,24 @@
// LeetCode {{NUMBER}} 單元測試xUnit
using Xunit;
public class SolutionTests {
private readonly Solution _s = new Solution();
[Fact]
public void Example1() {
// TODO: Arrange
// var input = new int[] { };
// var expected = 0;
// Act
// var got = _s.Solve(input);
// Assert.Equal(expected, got);
Assert.True(true);
}
[Fact]
public void EdgeCases() {
Assert.True(true);
}
}

View File

@@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="../csharp/csharp.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,20 @@
# 邊界情況清單({{NUMBER}} {{NAME_TITLE}}
## 需要測試的邊界
- [ ] 空輸入 / 單一元素
- [ ] 重複元素 / 全相同
- [ ] 極值(最小/最大)
- [ ] 含負數 / 0 / 大數
- [ ] 大資料量(接近上限)
## 額外案例
### 案例 1
- 輸入:
- 預期:
- 說明:
### 案例 2
- 輸入:
- 預期:
- 說明:

View File

@@ -0,0 +1,2 @@
# 測試案例 1 輸入({{NUMBER}} {{NAME_TITLE}}

View File

@@ -0,0 +1,2 @@
# 測試案例 2 輸入({{NUMBER}} {{NAME_TITLE}}

View File

@@ -0,0 +1,12 @@
// LeetCode {{NUMBER}} 單元測試Go testing
package main
import "testing"
func TestExample(t *testing.T) {
// TODO: input := []int{}
// got := solve(input)
// want := 0
// if got != want { t.Fatalf("want %v got %v", want, got) }
}

View File

@@ -0,0 +1,2 @@
# 測試案例 1 期望輸出({{NUMBER}} {{NAME_TITLE}}

View File

@@ -0,0 +1,2 @@
# 測試案例 2 期望輸出({{NUMBER}} {{NAME_TITLE}}

View File

@@ -0,0 +1,36 @@
#!/bin/bash
set -e
echo "🧪 執行測試: {{NUMBER_PAD}}-{{NAME_SLUG}}"
echo "=========================="
pushd "$(dirname "$0")" >/dev/null
echo "📋 C# 測試結果:"
if (cd ../csharp && dotnet build >/dev/null 2>&1); then
if dotnet test --logger "console;verbosity=minimal" >/dev/null 2>&1; then
echo "✅ C# 測試通過"
else
echo "❌ C# 測試失敗"
fi
else
echo "❌ C# 編譯失敗"
fi
echo ""
echo "📋 Go 測試結果:"
if (cd ../go && go build >/dev/null 2>&1); then
if go test -v >/dev/null 2>&1; then
echo "✅ Go 測試通過"
else
echo "❌ Go 測試失敗(顯示詳細)"
go test -v
fi
else
echo "❌ Go 編譯失敗"
fi
popd >/dev/null
echo ""
echo "📊 測試完成!"

169
utils/leetcode_helper.sh Executable file
View File

@@ -0,0 +1,169 @@
# 1. 讓腳本可執行:
# chmod +x utils/leetcode_helper.sh
# 2. 建立新題目:
# ./utils/leetcode_helper.sh problem 1 two-sum Easy
# ./utils/leetcode_helper.sh problem 3000 maximum-area-rectangle Medium
# 3. 建立月度日誌:
# ./utils/leetcode_helper.sh log 2025-09
# 4. 更新README
# ./utils/leetcode_helper.sh readme
#!/bin/bash
set -euo pipefail
# 路徑設定
SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
ROOT_DIR=$(cd "$SCRIPT_DIR/.." && pwd)
TEMPLATES_DIR="$ROOT_DIR/templates"
# kebab-case -> Title Casetwo-sum -> Two Sum
to_title_case() {
local s="${1//-/ }"
echo "$s" | awk '{for(i=1;i<=NF;i++){ $i=toupper(substr($i,1,1)) substr($i,2) } print }'
}
# 渲染模板到目的檔
# 變數:{{NUMBER}}, {{NUMBER_PAD}}, {{NAME_SLUG}}, {{NAME_TITLE}}, {{DIFFICULTY}}, {{DATE}}, {{YEAR_MONTH}}
render_template() {
local src="$1"; shift
local dest="$1"; shift
local number="${1:-}"; shift || true
local number_pad="${1:-}"; shift || true
local name_slug="${1:-}"; shift || true
local name_title="${1:-}"; shift || true
local difficulty="${1:-}"; shift || true
local today="${1:-}"; shift || true
local year_month="${1:-}"; shift || true
mkdir -p "$(dirname "$dest")"
sed -e "s/{{NUMBER}}/${number}/g" \
-e "s/{{NUMBER_PAD}}/${number_pad}/g" \
-e "s/{{NAME_SLUG}}/${name_slug}/g" \
-e "s/{{NAME_TITLE}}/${name_title}/g" \
-e "s/{{DIFFICULTY}}/${difficulty}/g" \
-e "s/{{DATE}}/${today}/g" \
-e "s/{{YEAR_MONTH}}/${year_month}/g" \
"$src" > "$dest"
}
# 建立測試檔案(來自 templates/problem/test/*
create_test_files() {
local problem_dir="$1"; local number="$2"; local name_slug="$3"; local difficulty="$4"
local number_pad=$(printf "%04d" "$number")
local name_title=$(to_title_case "$name_slug")
local today=$(date +%Y-%m-%d)
local year_month=$(date +%Y-%m)
render_template "$TEMPLATES_DIR/problem/test/SolutionTests.cs.tmpl" \
"$problem_dir/test/SolutionTests.cs" \
"$number" "$number_pad" "$name_slug" "$name_title" "$difficulty" "$today" "$year_month"
render_template "$TEMPLATES_DIR/problem/test/TestProject.csproj.tmpl" \
"$problem_dir/test/TestProject.csproj" \
"$number" "$number_pad" "$name_slug" "$name_title" "$difficulty" "$today" "$year_month"
render_template "$TEMPLATES_DIR/problem/test/main_test.go.tmpl" \
"$problem_dir/test/main_test.go" \
"$number" "$number_pad" "$name_slug" "$name_title" "$difficulty" "$today" "$year_month"
render_template "$TEMPLATES_DIR/problem/test/edge_cases.md.tmpl" \
"$problem_dir/test/edge_cases.md" \
"$number" "$number_pad" "$name_slug" "$name_title" "$difficulty" "$today" "$year_month"
render_template "$TEMPLATES_DIR/problem/test/input1.txt.tmpl" "$problem_dir/test/input1.txt" \
"$number" "$number_pad" "$name_slug" "$name_title" "$difficulty" "$today" "$year_month"
render_template "$TEMPLATES_DIR/problem/test/output1.txt.tmpl" "$problem_dir/test/output1.txt" \
"$number" "$number_pad" "$name_slug" "$name_title" "$difficulty" "$today" "$year_month"
render_template "$TEMPLATES_DIR/problem/test/input2.txt.tmpl" "$problem_dir/test/input2.txt" \
"$number" "$number_pad" "$name_slug" "$name_title" "$difficulty" "$today" "$year_month"
render_template "$TEMPLATES_DIR/problem/test/output2.txt.tmpl" "$problem_dir/test/output2.txt" \
"$number" "$number_pad" "$name_slug" "$name_title" "$difficulty" "$today" "$year_month"
render_template "$TEMPLATES_DIR/problem/test/run_tests.sh.tmpl" \
"$problem_dir/test/run_tests.sh" \
"$number" "$number_pad" "$name_slug" "$name_title" "$difficulty" "$today" "$year_month"
chmod +x "$problem_dir/test/run_tests.sh"
}
# 建立新題目
create_problem() {
local number="$1"; local name_slug="$2"; local difficulty="$3"
if [[ -z "${number:-}" || -z "${name_slug:-}" || -z "${difficulty:-}" ]]; then
echo "使用方法: $0 problem <題號> <題目名稱-kebab> <難度>"; exit 1
fi
local number_pad=$(printf "%04d" "$number")
local folder_name="${number_pad}-${name_slug}"
local problem_dir="$ROOT_DIR/problems/${folder_name}"
local name_title=$(to_title_case "$name_slug")
local today=$(date +%Y-%m-%d)
local year_month=$(date +%Y-%m)
mkdir -p "$problem_dir/csharp" "$problem_dir/go" "$problem_dir/test"
# README
render_template "$TEMPLATES_DIR/problem/README.md.tmpl" \
"$problem_dir/README.md" \
"$number" "$number_pad" "$name_slug" "$name_title" "$difficulty" "$today" "$year_month"
# C#
render_template "$TEMPLATES_DIR/problem/csharp/Program.cs.tmpl" \
"$problem_dir/csharp/Program.cs" \
"$number" "$number_pad" "$name_slug" "$name_title" "$difficulty" "$today" "$year_month"
render_template "$TEMPLATES_DIR/problem/csharp/csharp.csproj.tmpl" \
"$problem_dir/csharp/csharp.csproj" \
"$number" "$number_pad" "$name_slug" "$name_title" "$difficulty" "$today" "$year_month"
# Go
render_template "$TEMPLATES_DIR/problem/go/main.go.tmpl" \
"$problem_dir/go/main.go" \
"$number" "$number_pad" "$name_slug" "$name_title" "$difficulty" "$today" "$year_month"
(cd "$problem_dir/go" && go mod init "leetcode-$number" >/dev/null 2>&1 || true)
# Tests
create_test_files "$problem_dir" "$number" "$name_slug" "$difficulty"
echo "✅ 已建立題目: $problem_dir"
echo "C#: cd problems/${folder_name}/csharp && dotnet run"
echo "Go: cd problems/${folder_name}/go && go run main.go"
echo "測試: cd problems/${folder_name}/test && ./run_tests.sh"
}
# 更新主 README目前僅統計列印
update_readme() {
echo "🔄 更新主 README 統計..."
local total_problems=$(find "$ROOT_DIR/problems" -maxdepth 1 -type d | wc -l)
total_problems=$((total_problems - 1))
local completed_problems=$(find "$ROOT_DIR/problems" -name "README.md" -exec grep -l "✅" {} \; | wc -l)
echo "📊 題目總數: $total_problems,標記完成: $completed_problems"
}
# 建立月度日誌(由模板 logs-template.md.tmpl 渲染)
create_monthly_log() {
local year_month="${1:-}"
if [[ -z "$year_month" ]]; then year_month=$(date +%Y-%m); fi
local dest="$ROOT_DIR/logs/${year_month}.md"
if [[ -f "$dest" ]]; then echo "⚠️ 已存在: $dest"; return 1; fi
mkdir -p "$ROOT_DIR/logs"
render_template "$TEMPLATES_DIR/logs-template.md.tmpl" "$dest" "" "" "" "" "" "" "$year_month"
echo "✅ 已建立月度日誌: $dest"
}
# 入口
case "${1:-}" in
problem)
create_problem "${2:-}" "${3:-}" "${4:-}" ;;
readme)
update_readme ;;
log)
create_monthly_log "${2:-}" ;;
*)
echo "LeetCode Practice Helper"
echo "使用:"
echo " $0 problem <題號> <題目名稱-kebab> <難度>"
echo " $0 readme"
echo " $0 log [YYYY-MM]"
;;
esac