From ed0d2f344dd3186ee26ecd35450a54cb7d761f4d Mon Sep 17 00:00:00 2001 From: MH Hung Date: Mon, 1 Sep 2025 09:48:11 +0800 Subject: [PATCH] feat(template): add readme templates and leetcode helper --- README.md | 88 +++++- leetcode_helper.sh | 586 +++++++++++++++++++++++++++++++++++++ logs/2025-09.md | 0 templates/logs-template.md | 86 ++++++ 4 files changed, 756 insertions(+), 4 deletions(-) create mode 100755 leetcode_helper.sh create mode 100644 logs/2025-09.md create mode 100644 templates/logs-template.md diff --git a/README.md b/README.md index ba7ea24..c672611 100755 --- a/README.md +++ b/README.md @@ -1,5 +1,85 @@ -# coding-practice +# LeetCode Practice Journey 🚀 -Practice from Daily Leetcode -ACC : iak64825@jioso.com -Password : ww5&Hy73dgh \ No newline at end of file +## 📊 進度統計 +- **總題數**: 0 +- **已完成**: 0 +- **開始日期**: 2025-09-01 +- **最後更新**: 2025-09-01 + +### 難度分布 +| 難度 | 完成數 | 總數 | 進度 | +|------|--------|------|------| +| Easy | 0 | 0 | 0% | +| Medium | 0 | 0 | 0% | +| Hard | 0 | 0 | 0% | + +### 語言分布 +| 語言 | 完成題數 | +|------|----------| +| C++ | 0 | +| C# | 0 | +| Go | 0 | + +## 🎯 學習目標 +- [ ] 熟悉基本資料結構 (Array, LinkedList, Stack, Queue) +- [ ] 掌握雙指針技巧 +- [ ] 動態規劃入門 (目標:完成 10 題) +- [ ] 樹和圖的遍歷 +- [ ] 二分搜尋應用 + +## 📚 題目分類 + +### Array & Hash Table +| 題號 | 題目 | 難度 | 狀態 | 語言 | 筆記 | +|------|------|------|------|------|------| +| 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 +| 題號 | 題目 | 難度 | 狀態 | 語言 | 筆記 | +|------|------|------|------|------|------| +| 3 | [Longest Substring Without Repeating Characters](problems/0003-longest-substring/) | Medium | 🔄 | C# | 滑動窗口 | + +### Dynamic Programming +| 題號 | 題目 | 難度 | 狀態 | 語言 | 筆記 | +|------|------|------|------|------|------| +| 70 | [Climbing Stairs](problems/0070-climbing-stairs/) | Easy | 📝 | - | 待開始 | + +## 📅 月度學習記錄 +- [2025年9月](logs/2025-09.md) - 基礎入門月 (完成 8 題) +- [2025年10月](logs/2025-09.md) - 進階提升月 (進行中...) + +## 🧠 重點學習筆記 + +### 常用模式總結 +1. **雙指針**: 適用於有序陣列的搜尋問題 +2. **滑動窗口**: 子陣列/子字串的最佳化問題 +3. **Hash Map**: 快速查找和計數問題 + +### 容易出錯的地方 +- 邊界條件檢查 (空陣列、單一元素) +- 整數溢位問題 +- 陣列索引越界 + +## 📈 學習曲線反思 +- **第一週**: 熟悉基本語法和 LeetCode 平台 +- **第二週**: 開始理解演算法思維 +- **第三週**: 能獨立分析中等難度題目 +- **第四週**: 開始關注時間空間複雜度最佳化 + +## 🔗 有用資源 +- [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) + +--- +*最後更新: 2025-09-01* + +--- +account : iak64825@jioso.com +password : ww5&Hy73dgh \ No newline at end of file diff --git a/leetcode_helper.sh b/leetcode_helper.sh new file mode 100755 index 0000000..5f00128 --- /dev/null +++ b/leetcode_helper.sh @@ -0,0 +1,586 @@ +# 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 + + + + net6.0 + enable + false + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + + +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 -n "Problem$number" --force > /dev/null 2>&1 + + # 建立 C# 解法檔案 + 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 "│ └── Problem$number.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 \ No newline at end of file diff --git a/logs/2025-09.md b/logs/2025-09.md new file mode 100644 index 0000000..e69de29 diff --git a/templates/logs-template.md b/templates/logs-template.md new file mode 100644 index 0000000..c409ad1 --- /dev/null +++ b/templates/logs-template.md @@ -0,0 +1,86 @@ +# 2025年8月 學習記錄 + +## 📅 每日練習記錄 + +### Week 1 (2025-08-01 ~ 2025-08-07) +| 日期 | 題目 | 難度 | 語言 | 耗時 | 狀態 | 心得 | +|------|------|------|------|------|------|------| +| 08-01 | [1] Two Sum | Easy | C# | 30min | ✅ | 第一題,熟悉環境 | +| 08-02 | [1] Two Sum | Easy | Go | 45min | ✅ | Go語法不熟,多花時間 | +| 08-03 | [15] 3Sum | Medium | C# | 90min | ⚠️ | TLE,需要最佳化 | +| 08-04 | [15] 3Sum | Medium | C# | 60min | ✅ | 學會雙指針,重要突破! | +| 08-05 | 休息 | - | - | - | - | 週末休息 | +| 08-06 | [11] Container Water | Medium | C# | 45min | ✅ | 雙指針再次應用 | +| 08-07 | 複習筆記 | - | - | 60min | - | 整理本週學習 | + +### Week 2 (2025-08-08 ~ 2025-08-14) +| 日期 | 題目 | 難度 | 語言 | 耗時 | 狀態 | 心得 | +|------|------|------|------|------|------|------| +| 08-08 | [3] Longest Substring | Medium | C# | 120min | 🔄 | 滑動窗口概念很重要 | +| 08-09 | [3] Longest Substring | Medium | Go | 90min | ✅ | Go實作更簡潔 | +| ... | ... | ... | ... | ... | ... | ... | + +## 📈 本月統計 + +### 完成情況 +- **總練習天數**: 20天 +- **完成題數**: 8題 +- **語言分布**: C# (8題), Go (5題) +- **難度分布**: Easy (5題), Medium (3題), Hard (0題) + +### 時間投入 +- **總時間**: 18小時 +- **平均每題**: 135分鐘 +- **每日平均**: 54分鐘 + +### 正確率 +- **一次通過**: 3題 (37.5%) +- **二次通過**: 4題 (50%) +- **多次調整**: 1題 (12.5%) + +## 🎯 本月重點學習 + +### 新掌握的技巧 +1. **雙指針技巧** - 在 3Sum 和 Container Water 中應用 +2. **Hash Table 應用** - Two Sum 的經典解法 +3. **滑動窗口初步** - Longest Substring 問題 + +### 常犯錯誤分析 +1. **邊界條件** - 忘記檢查空陣列 (犯錯 3次) +2. **索引越界** - 雙指針移動時的邊界 (犯錯 2次) +3. **時間複雜度** - 第一次嘗試常用暴力解法 + +### 語言學習心得 +- **C#**: 語法熟悉,LINQ很好用但要注意效能 +- **Go**: 簡潔但型別嚴格,slice操作需多練習 + +## 🔄 遇到的困難與解決 + +### 困難1: 思路卡住 +- **問題**: 3Sum 一開始完全沒思路 +- **解決**: 先研究 Two Sum,再擴展到三個數字 +- **學習**: 從簡單問題推廣到複雜問題 + +### 困難2: Go語法不熟 +- **問題**: Go的slice、map語法經常出錯 +- **解決**: 整理了Go語法筆記,多做練習 +- **學習**: 不要急著解題,先把工具準備好 + +## 📝 改進計畫 + +### 9月目標 +1. **提升難度**: 嘗試3-5題Hard題目 +2. **新主題**: 開始學習動態規劃 +3. **效率提升**: 目標平均解題時間降到90分鐘 +4. **語言平衡**: Go語言題數追上C# + +### 學習方法調整 +1. **題目分析時間**: 每題先花15分鐘分析再開始寫程式 +2. **複習機制**: 每週末複習本週所有題目 +3. **筆記改善**: 加強解題思路的記錄 + +## 💡 本月金句 +> "演算法不是背出來的,是理解出來的" - 在第15題3Sum卡住兩天後的感悟 + +--- +**總結**: 八月是很好的開始,從完全新手到能獨立解決中等題目。九月要持續挑戰自己! \ No newline at end of file