Compare commits
17 Commits
f4a7029b7e
...
main
Author | SHA1 | Date | |
---|---|---|---|
8146e2176d | |||
5189c524ef | |||
959f8a6861 | |||
5f8bf18795 | |||
72aa011de9 | |||
c4e23d5be3 | |||
c7453b45e6 | |||
7c86a4a99a | |||
c396a84294 | |||
2d6209a043 | |||
1e562065e8 | |||
8dfafaaf43 | |||
6d9993cd9f | |||
9ff736e11c | |||
d724a5fb65 | |||
002e9e6c32 | |||
75f3d9e320 |
338
README.md
338
README.md
@@ -1,85 +1,289 @@
|
||||
# LeetCode Practice Journey 🚀
|
||||
# LeetCode 練習專案
|
||||
|
||||
## 📊 進度統計
|
||||
- **總題數**: 0
|
||||
- **已完成**: 0
|
||||
- **開始日期**: 2025-09-01
|
||||
- **最後更新**: 2025-09-01
|
||||
這是一個用來紀錄與管理 LeetCode 練習的專案,整合 C# 與 Go 的題解、基本測試模板、月度學習日誌,以及一支小工具腳本,協助快速建立新題目與維持一致的結構與習慣。
|
||||
|
||||
### 難度分布
|
||||
| 難度 | 完成數 | 總數 | 進度 |
|
||||
|------|--------|------|------|
|
||||
| Easy | 0 | 0 | 0% |
|
||||
| Medium | 0 | 0 | 0% |
|
||||
| Hard | 0 | 0 | 0% |
|
||||
## 專案架構
|
||||
|
||||
### 語言分布
|
||||
| 語言 | 完成題數 |
|
||||
|------|----------|
|
||||
| C++ | 0 |
|
||||
| C# | 0 |
|
||||
| Go | 0 |
|
||||
```
|
||||
.
|
||||
├── 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
|
||||
```
|
||||
|
||||
## 🎯 學習目標
|
||||
- [ ] 熟悉基本資料結構 (Array, LinkedList, Stack, Queue)
|
||||
- [ ] 掌握雙指針技巧
|
||||
- [ ] 動態規劃入門 (目標:完成 10 題)
|
||||
- [ ] 樹和圖的遍歷
|
||||
- [ ] 二分搜尋應用
|
||||
命名慣例:問題資料夾以「4 位數題號 + 題目英文 kebab-case」命名,例如 `3025-find-the-number-of-ways-to-place-people-i`。
|
||||
|
||||
## 📚 題目分類
|
||||
## 需求與環境
|
||||
|
||||
### Array & Hash Table
|
||||
| 題號 | 題目 | 難度 | 狀態 | 語言 | 筆記 |
|
||||
|------|------|------|------|------|------|
|
||||
| 1 | [Two Sum](problems/0001-two-sum/) | Easy | ✅ | C#, Go | 經典入門題 |
|
||||
| 15 | [3Sum](problems/0015-3sum/) | Medium | ✅ | C#, Go | 雙指針技巧 |
|
||||
- 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`
|
||||
|
||||
### 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# | 滑動窗口 |
|
||||
```
|
||||
chmod +x utils/leetcode_helper.sh utils/run_tests.sh
|
||||
```
|
||||
|
||||
### Dynamic Programming
|
||||
| 題號 | 題目 | 難度 | 狀態 | 語言 | 筆記 |
|
||||
|------|------|------|------|------|------|
|
||||
| 70 | [Climbing Stairs](problems/0070-climbing-stairs/) | Easy | 📝 | - | 待開始 |
|
||||
## 常用操作
|
||||
|
||||
## 📅 月度學習記錄
|
||||
- [2025年9月](logs/2025-09.md) - 基礎入門月 (完成 8 題)
|
||||
- [2025年10月](logs/2025-09.md) - 進階提升月 (進行中...)
|
||||
- 新增題目(自動建立資料夾、README、C#/Go 程式與測試模板)
|
||||
|
||||
## 🧠 重點學習筆記
|
||||
```
|
||||
./utils/leetcode_helper.sh problem <題號> <題目名稱-kebab> <難度>
|
||||
|
||||
### 常用模式總結
|
||||
1. **雙指針**: 適用於有序陣列的搜尋問題
|
||||
2. **滑動窗口**: 子陣列/子字串的最佳化問題
|
||||
3. **Hash Map**: 快速查找和計數問題
|
||||
# 範例
|
||||
./utils/leetcode_helper.sh problem 1 two-sum Easy
|
||||
./utils/leetcode_helper.sh problem 3000 maximum-area-rectangle Medium
|
||||
# 顯示說明:
|
||||
./utils/leetcode_helper.sh --help
|
||||
```
|
||||
|
||||
### 容易出錯的地方
|
||||
- 邊界條件檢查 (空陣列、單一元素)
|
||||
- 整數溢位問題
|
||||
- 陣列索引越界
|
||||
建立完成後的結構(示意):
|
||||
|
||||
## 📈 學習曲線反思
|
||||
- **第一週**: 熟悉基本語法和 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
|
||||
└── edge_cases.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)
|
||||
- 建立月度日誌(依模板生成 `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]`
|
||||
- <problem> 可為題號(如 `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#)
|
||||
|
||||
```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`
|
||||
不需修改腳本本身即可客製化模板。
|
||||
|
||||
## 工具清單
|
||||
|
||||
- `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]`
|
||||
- <problem> 可為:題號(如 `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、邊界測資)
|
||||
|
||||
---
|
||||
*最後更新: 2025-09-01*
|
||||
|
||||
---
|
||||
account : iak64825@jioso.com
|
||||
password : ww5&Hy73dgh
|
||||
歡迎依個人習慣調整腳本與模板,持續穩定地練習最重要!
|
||||
|
@@ -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
|
@@ -1,24 +0,0 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.5.2.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "largestGoodInteger", "largestGoodInteger.csproj", "{DF73131C-3A52-FFDC-7C0C-19190AA3E331}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{DF73131C-3A52-FFDC-7C0C-19190AA3E331}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{DF73131C-3A52-FFDC-7C0C-19190AA3E331}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{DF73131C-3A52-FFDC-7C0C-19190AA3E331}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{DF73131C-3A52-FFDC-7C0C-19190AA3E331}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {E9F3A871-90C4-4B8E-81E2-B0AF873694BF}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
@@ -1,63 +0,0 @@
|
||||
public class Solution {
|
||||
public string LargestGoodInteger(string num)
|
||||
{
|
||||
// var count = 0;
|
||||
// char lastNum = 'a';
|
||||
// var numList = new List<int>();
|
||||
// for (var i = 0; i < num.Length; i++)
|
||||
// {
|
||||
// if (num[i] == lastNum)
|
||||
// {
|
||||
// count++;
|
||||
// if (count == 3)
|
||||
// {
|
||||
// numList.Add(int.Parse(num[i].ToString()));
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// count = 1;
|
||||
// }
|
||||
|
||||
// lastNum = num[i];
|
||||
// }
|
||||
|
||||
// if (numList.Count == 0)
|
||||
// {
|
||||
// return "";
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// var a = numList.Max().ToString();
|
||||
// return $"{a}{a}{a}";
|
||||
// }
|
||||
|
||||
string max = "";
|
||||
|
||||
for (int i = 0; i < num.Length - 2; i++)
|
||||
{
|
||||
if (num[i] == num[i + 1] && num[i] == num[i + 2])
|
||||
{
|
||||
string current = $"{num[i]}{num[i]}{num[i]}";
|
||||
|
||||
if (max == "") max = current;
|
||||
else
|
||||
{
|
||||
if (int.Parse(current) > int.Parse(max))
|
||||
max = current;
|
||||
}
|
||||
}
|
||||
}
|
||||
return max;
|
||||
}
|
||||
}
|
||||
|
||||
class program
|
||||
{
|
||||
static void Main()
|
||||
{
|
||||
var solution = new Solution();
|
||||
|
||||
Console.WriteLine(solution.LargestGoodInteger("6777133339"));
|
||||
}
|
||||
}
|
@@ -1,23 +0,0 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func LargestGoodInteger(num string) string {
|
||||
max := ""
|
||||
|
||||
for i := 0; i < len(num)-2; i++ {
|
||||
if num[i] == num[i+1] && num[i] == num[i+2] {
|
||||
current := string([]byte{num[i], num[i], num[i]})
|
||||
|
||||
if current > max {
|
||||
max = current
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return max
|
||||
}
|
||||
|
||||
func main() {
|
||||
fmt.Println(LargestGoodInteger("7636669283"))
|
||||
}
|
@@ -1,24 +0,0 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.5.2.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProductQueries", "C#\ProductQueries.csproj", "{412F89C4-B1BF-D819-298B-9C873A098742}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{412F89C4-B1BF-D819-298B-9C873A098742}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{412F89C4-B1BF-D819-298B-9C873A098742}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{412F89C4-B1BF-D819-298B-9C873A098742}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{412F89C4-B1BF-D819-298B-9C873A098742}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {BDF3A5A3-29B8-4169-8A46-A13A7DE900D8}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
@@ -1,69 +0,0 @@
|
||||
using System;
|
||||
|
||||
public class Solution
|
||||
{
|
||||
public int[] ProductQueries(int n, int[][] queries)
|
||||
{
|
||||
// 1. n => calculate in powers of 2
|
||||
// 2. get number array without 0
|
||||
var powers = CalPower(n);
|
||||
|
||||
return CalQueries(powers, queries);
|
||||
|
||||
}
|
||||
|
||||
private int[] CalPower(int n)
|
||||
{
|
||||
var result = new List<int>();
|
||||
|
||||
while (n > 0)
|
||||
{
|
||||
var num = n % 2;
|
||||
result.Add(num);
|
||||
n /= 2;
|
||||
}
|
||||
|
||||
var newResult = new List<int>();
|
||||
for (var i = 0; i < result.Count; i++)
|
||||
{
|
||||
if (result[i] != 0)
|
||||
{
|
||||
var ans = (int)Math.Pow(2, i);
|
||||
newResult.Add(ans);
|
||||
}
|
||||
}
|
||||
return newResult.ToArray();
|
||||
}
|
||||
|
||||
private int[] CalQueries(int[] powers, int[][] queries)
|
||||
{
|
||||
const int MOD = 1000000007;
|
||||
var result = new List<int>();
|
||||
|
||||
foreach (var query in queries)
|
||||
{
|
||||
long count = 1;
|
||||
for (var i = query[0]; i <= query[1]; i++)
|
||||
{
|
||||
count = (count * powers[i]) % MOD;
|
||||
}
|
||||
result.Add(count);
|
||||
}
|
||||
|
||||
return result.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
class Program
|
||||
{
|
||||
static void Main()
|
||||
{
|
||||
var Solution = new Solution();
|
||||
|
||||
var ans = Solution.ProductQueries(15, [[0, 1], [2, 2], [0, 3]]);
|
||||
Console.WriteLine(string.Join(", ", ans));
|
||||
|
||||
ans = Solution.ProductQueries(919, [[5,5],[4,4],[0,1],[1,5],[4,6],[6,6],[5,6],[0,3],[5,5],[5,6],[1,2],[3,5],[3,6],[5,5],[4,4],[1,1],[2,4],[4,5],[4,4],[5,6],[0,4],[3,3],[0,4],[0,5],[4,4],[5,5],[4,6],[4,5],[0,4],[6,6],[6,6],[6,6],[2,2],[0,5],[1,4],[0,3],[2,4],[5,5],[6,6],[2,2],[2,3],[5,5],[0,6],[3,3],[6,6],[4,4],[0,0],[0,2],[6,6],[6,6],[3,6],[0,4],[6,6],[2,2],[4,6]]);
|
||||
Console.WriteLine(string.Join(", ", ans));
|
||||
}
|
||||
}
|
@@ -1,5 +0,0 @@
|
||||
Given a positive integer n, there exists a 0-indexed array called powers, composed of the minimum number of powers of 2 that sum to n. The array is sorted in non-decreasing order, and there is only one way to form the array.
|
||||
|
||||
You are also given a 0-indexed 2D integer array queries, where queries[i] = [lefti, righti]. Each queries[i] represents a query where you have to find the product of all powers[j] with lefti <= j <= righti.
|
||||
|
||||
Return an array answers, equal in length to queries, where answers[i] is the answer to the ith query. Since the answer to the ith query may be too large, each answers[i] should be returned modulo 109 + 7.
|
@@ -1,24 +0,0 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.5.2.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "numberOfWays", "numberOfWays.csproj", "{1E81E272-AF2C-9CB4-F90B-0AAC263D10DC}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{1E81E272-AF2C-9CB4-F90B-0AAC263D10DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{1E81E272-AF2C-9CB4-F90B-0AAC263D10DC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{1E81E272-AF2C-9CB4-F90B-0AAC263D10DC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{1E81E272-AF2C-9CB4-F90B-0AAC263D10DC}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {AD18FC84-E2FB-4382-96DF-8AE7E50C1401}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
@@ -1,48 +0,0 @@
|
||||
// knapsack problem
|
||||
public class Solution
|
||||
{
|
||||
public int NumberOfWays(int n, int x)
|
||||
{
|
||||
const int MOD = 1_000_000_007;
|
||||
// list all the powers which smaller than n
|
||||
var powers = new List<int>();
|
||||
var num = 1;
|
||||
|
||||
while (true)
|
||||
{
|
||||
int pow = (int)Math.Pow(num, x);
|
||||
if (pow > n)
|
||||
break;
|
||||
powers.Add(pow);
|
||||
num++;
|
||||
}
|
||||
|
||||
// dynamic programming
|
||||
var dp = new int[n + 1];
|
||||
dp[0] = 1;
|
||||
|
||||
foreach (var power in powers)
|
||||
{
|
||||
for (var i = n; i >= power; i--)
|
||||
{
|
||||
dp[i] = (dp[i] + dp[i - power]) % MOD;
|
||||
}
|
||||
}
|
||||
|
||||
return dp[n];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class Program
|
||||
{
|
||||
static void Main()
|
||||
{
|
||||
var solution = new Solution();
|
||||
|
||||
Console.WriteLine(solution.NumberOfWays(4, 1));
|
||||
Console.WriteLine(solution.NumberOfWays(100, 3));
|
||||
|
||||
}
|
||||
}
|
@@ -1,38 +0,0 @@
|
||||
public class Solution
|
||||
{
|
||||
public int AreaOfMaxDiagonal(int[][] dimensions)
|
||||
{
|
||||
int max = 0;
|
||||
int maxArea = 0;
|
||||
|
||||
foreach (var dimension in dimensions)
|
||||
{
|
||||
var dimensionSqrt = dimension[0] * dimension[0] + dimension[1] * dimension[1];
|
||||
var area = dimension[0] * dimension[1];
|
||||
if (dimensionSqrt > max)
|
||||
{
|
||||
max = dimensionSqrt;
|
||||
maxArea = area;
|
||||
}
|
||||
else if (dimensionSqrt == max)
|
||||
{
|
||||
maxArea = Math.Max(maxArea, area);
|
||||
}
|
||||
}
|
||||
return maxArea;
|
||||
}
|
||||
}
|
||||
|
||||
public class Program
|
||||
{
|
||||
public static void Main()
|
||||
{
|
||||
var Solution = new Solution();
|
||||
|
||||
var dimensions = new int[][] { [6,5],[8,6],[2,10],[8,1],[9,2],[3,5],[3,5]};
|
||||
|
||||
var result = Solution.AreaOfMaxDiagonal(dimensions);
|
||||
Console.WriteLine(result);
|
||||
}
|
||||
}
|
||||
|
@@ -1,27 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
)
|
||||
|
||||
func areaOfMaxDiagonal(dimensions [][]int) int{
|
||||
maxDiagonal := 0
|
||||
maxArea := 0
|
||||
|
||||
for _, dimension := range dimensions{
|
||||
l := dimension[0]
|
||||
w := dimension[1]
|
||||
diagonalSquare := l * l + w * w
|
||||
area := l * w
|
||||
|
||||
if diagonalSquare > maxDiagonal{
|
||||
maxDiagonal = diagonalSquare
|
||||
maxArea = area
|
||||
}else if diagonalSquare == maxDiagonal{
|
||||
maxArea = int(math.Max(float64(maxArea), float64(area)))
|
||||
}
|
||||
}
|
||||
|
||||
return maxArea
|
||||
}
|
@@ -1,24 +0,0 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.5.2.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MinimumArea", "MinimumArea.csproj", "{61A8B87F-638B-4246-13C4-CC226CFBBEA5}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{61A8B87F-638B-4246-13C4-CC226CFBBEA5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{61A8B87F-638B-4246-13C4-CC226CFBBEA5}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{61A8B87F-638B-4246-13C4-CC226CFBBEA5}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{61A8B87F-638B-4246-13C4-CC226CFBBEA5}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {C6FDF6F7-60CD-4B35-B619-6F79B7243CA7}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
@@ -1,28 +0,0 @@
|
||||
public class Solution {
|
||||
public int MinimumArea(int[][] grid)
|
||||
{
|
||||
var x = grid[0].Length;
|
||||
var y = grid.Length;
|
||||
|
||||
int min_x = x;
|
||||
int max_x = 0;
|
||||
int min_y = y;
|
||||
int max_y = 0;
|
||||
|
||||
for (var i = 0; i < x; i++)
|
||||
{
|
||||
for (var j = 0; j < y; j++)
|
||||
{
|
||||
if (grid[j][i])
|
||||
{
|
||||
min_x = Math.Min(min_x, i);
|
||||
max_x = Math.Max(max_x, i);
|
||||
min_y = Math.Min(min_y, j);
|
||||
max_y = Math.Max(max_y, j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (max_x - min_x + 1) * (max_y - min_y + 1);
|
||||
}
|
||||
}
|
@@ -1,40 +0,0 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func minimumArea(grid [][]int) int {
|
||||
row := len(grid)
|
||||
col := len(grid[0])
|
||||
|
||||
min_x := col
|
||||
max_x := 0
|
||||
min_y := row
|
||||
max_y := 0
|
||||
|
||||
for i:=0; i<row; i++{
|
||||
for j:=0; j<col; j++{
|
||||
if grid[i][j] == 1{
|
||||
min_x = Min(min_x, j)
|
||||
max_x = Max(max_x, j)
|
||||
min_y = Min(min_y, i)
|
||||
max_y = Max(max_y, i)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (max_x-min_x+1) * (max_y-min_y+1)
|
||||
}
|
||||
|
||||
func Min(a, b int)int{
|
||||
if a < b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
func Max(a, b int)int{
|
||||
if a > b{
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
@@ -1,21 +0,0 @@
|
||||
public class Solution {
|
||||
public bool IsPowerOfThree(int n) {
|
||||
if(n <= 0)
|
||||
return false;
|
||||
if(n == 1)
|
||||
return true;
|
||||
if(n % 3 != 0)
|
||||
return false;
|
||||
return IsPowerOfThree(n/3);
|
||||
}
|
||||
}
|
||||
|
||||
class program{
|
||||
static void Main(){
|
||||
var Solution = new Solution();
|
||||
|
||||
Console.WriteLine(Solution.IsPowerOfThree(9));
|
||||
Console.WriteLine(Solution.IsPowerOfThree(0));
|
||||
Console.WriteLine(Solution.IsPowerOfThree(-1));
|
||||
}
|
||||
}
|
@@ -1,10 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
@@ -1,22 +0,0 @@
|
||||
Given an integer n, return true if it is a power of three. Otherwise, return false.
|
||||
|
||||
An integer n is a power of three, if there exists an integer x such that n == 3x.
|
||||
|
||||
|
||||
|
||||
Example 1:
|
||||
|
||||
Input: n = 27
|
||||
Output: true
|
||||
Explanation: 27 = 33
|
||||
Example 2:
|
||||
|
||||
Input: n = 0
|
||||
Output: false
|
||||
Explanation: There is no x where 3x = 0.
|
||||
Example 3:
|
||||
|
||||
Input: n = -1
|
||||
Output: false
|
||||
Explanation: There is no x where 3x = (-1).
|
||||
|
@@ -1,26 +0,0 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
type Solution struct{}
|
||||
|
||||
func (s Solution) IsPowerOfThree(n int) bool{
|
||||
if n <= 0{
|
||||
return false
|
||||
}
|
||||
if n == 1{
|
||||
return true
|
||||
}
|
||||
if n % 3 != 0{
|
||||
return false
|
||||
}
|
||||
return s.IsPowerOfThree(n/3)
|
||||
}
|
||||
|
||||
func main(){
|
||||
solution := Solution{}
|
||||
|
||||
fmt.Println(solution.IsPowerOfThree(27))
|
||||
fmt.Println(solution.IsPowerOfThree(0))
|
||||
fmt.Println(solution.IsPowerOfThree(-1))
|
||||
}
|
@@ -1,10 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
@@ -1,24 +0,0 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.5.2.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MaxCollectedFruits", "MaxCollectedFruits.csproj", "{AA67CF61-67B3-7229-E3F9-D471B0EF4EDE}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{AA67CF61-67B3-7229-E3F9-D471B0EF4EDE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{AA67CF61-67B3-7229-E3F9-D471B0EF4EDE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{AA67CF61-67B3-7229-E3F9-D471B0EF4EDE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{AA67CF61-67B3-7229-E3F9-D471B0EF4EDE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {B9D47F51-61C3-4A24-890A-01C9AC85EC93}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
@@ -1,67 +0,0 @@
|
||||
public class Solution
|
||||
{
|
||||
public int MaxCollectedFruits(int[][] fruits)
|
||||
{
|
||||
int n = fruits.Length;
|
||||
int ans = 0;
|
||||
for (int i = 0; i < n; ++i) ans += fruits[i][i];
|
||||
|
||||
int dp()
|
||||
{
|
||||
int[] prev = Enumerable.Repeat(int.MinValue, n).ToArray();
|
||||
int[] curr = new int[n];
|
||||
prev[n - 1] = fruits[0][n - 1];
|
||||
for (int i = 1; i < n - 1; ++i)
|
||||
{
|
||||
Array.Fill(curr, int.MinValue);
|
||||
for (int j = Math.Max(n - 1 - i, i + 1); j < n; ++j)
|
||||
{
|
||||
int best = prev[j];
|
||||
if (j - 1 >= 0)
|
||||
{
|
||||
best = Math.Max(best, prev[j - 1]);
|
||||
}
|
||||
if (j + 1 < n)
|
||||
{
|
||||
best = Math.Max(best, prev[j + 1]);
|
||||
}
|
||||
curr[j] = best + fruits[i][j];
|
||||
}
|
||||
var temp = prev;
|
||||
prev = curr;
|
||||
curr = temp;
|
||||
}
|
||||
return prev[n - 1];
|
||||
}
|
||||
|
||||
ans += dp();
|
||||
|
||||
for (int i = 0; i < n; ++i)
|
||||
{
|
||||
for (int j = 0; j < i; ++j)
|
||||
{
|
||||
var temp = fruits[j][i];
|
||||
fruits[j][i] = fruits[i][j];
|
||||
fruits[i][j] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
ans += dp();
|
||||
return ans;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
class Program
|
||||
{
|
||||
static void Main()
|
||||
{
|
||||
var Solution = new Solution();
|
||||
|
||||
var fruits = new int[][] { [1,2,3,4],[5,6,8,7],[9,10,11,12],[13,14,15,16]};
|
||||
|
||||
Console.WriteLine(Solution.MaxCollectedFruits(fruits));
|
||||
}
|
||||
}
|
@@ -1,24 +0,0 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.5.2.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SortMatrix", "SortMatrix.csproj", "{60318F94-4F41-A4B8-C189-A8135ECCECCB}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{60318F94-4F41-A4B8-C189-A8135ECCECCB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{60318F94-4F41-A4B8-C189-A8135ECCECCB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{60318F94-4F41-A4B8-C189-A8135ECCECCB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{60318F94-4F41-A4B8-C189-A8135ECCECCB}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {9F59D1F6-D9F3-492C-BC39-A5771AF22B36}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
@@ -1,115 +0,0 @@
|
||||
public class Solution
|
||||
{
|
||||
public int[][] SortMatrix(int[][] grid)
|
||||
{
|
||||
// 左下
|
||||
var leftDiagonals = new Dictionary<int, List<int>>();
|
||||
for (var i = 0; i < grid.Length; i++)
|
||||
{
|
||||
// total -> 2n + 1 way
|
||||
for (var j = 0; j <= i; j++)
|
||||
{
|
||||
int diagonal = i - j;
|
||||
if (!leftDiagonals.ContainsKey(diagonal))
|
||||
{
|
||||
leftDiagonals[diagonal] = new List<int>();
|
||||
}
|
||||
leftDiagonals[diagonal].Add(grid[i][j]);
|
||||
}
|
||||
}
|
||||
|
||||
// 右上
|
||||
var rightDiagonals = new Dictionary<int, List<int>>();
|
||||
for (var i = 0; i < grid.Length; i++)
|
||||
{
|
||||
for (var j = i; j < grid.Length; j++)
|
||||
{
|
||||
int diagonal = j - i;
|
||||
if (!rightDiagonals.ContainsKey(diagonal))
|
||||
{
|
||||
rightDiagonals[diagonal] = new List<int>();
|
||||
}
|
||||
rightDiagonals[diagonal].Add(grid[i][j]);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var diagonal in leftDiagonals.Values)
|
||||
{
|
||||
diagonal.Sort((a, b) => b.CompareTo(a));
|
||||
}
|
||||
|
||||
foreach (var diagonal in rightDiagonals.Values)
|
||||
{
|
||||
diagonal.Sort((a, b) => a.CompareTo(b));
|
||||
}
|
||||
|
||||
for (var i = 0; i < grid.Length; i++)
|
||||
{
|
||||
for (var j = 0; j <= i; j++)
|
||||
{
|
||||
int diagonal = i - j;
|
||||
grid[i][j] = leftDiagonals[diagonal][0];
|
||||
leftDiagonals[diagonal].RemoveAt(0);
|
||||
}
|
||||
|
||||
for (var j = i; j < grid.Length; j++)
|
||||
{
|
||||
if (i == j) continue;
|
||||
int diagonal = j - i;
|
||||
grid[i][j] = rightDiagonals[diagonal][0];
|
||||
rightDiagonals[diagonal].RemoveAt(0);
|
||||
}
|
||||
}
|
||||
return grid;
|
||||
}
|
||||
}
|
||||
|
||||
public class Solution2 {
|
||||
public int[][] SortMatrix(int[][] grid) {
|
||||
int n = grid.Length;
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
List<int> tmp = new List<int>();
|
||||
for (int j = 0; i + j < n; j++) {
|
||||
tmp.Add(grid[i + j][j]);
|
||||
}
|
||||
tmp.Sort((a, b) => b.CompareTo(a));
|
||||
for (int j = 0; i + j < n; j++) {
|
||||
grid[i + j][j] = tmp[j];
|
||||
}
|
||||
}
|
||||
|
||||
for (int j = 1; j < n; j++) {
|
||||
List<int> tmp = new List<int>();
|
||||
for (int i = 0; j + i < n; i++) {
|
||||
tmp.Add(grid[i][j + i]);
|
||||
}
|
||||
tmp.Sort();
|
||||
for (int i = 0; j + i < n; i++) {
|
||||
grid[i][j + i] = tmp[i];
|
||||
}
|
||||
}
|
||||
|
||||
return grid;
|
||||
}
|
||||
}
|
||||
|
||||
class Program
|
||||
{
|
||||
static void Main()
|
||||
{
|
||||
var Solution = new Solution();
|
||||
|
||||
var gird = new int[][] { [1, 7, 3], [9, 8, 2], [4, 5, 6] };
|
||||
var result = Solution.SortMatrix(gird);
|
||||
|
||||
for (int i = 0; i < result.Length; i++)
|
||||
{
|
||||
for (int j = 0; j < result[i].Length; j++)
|
||||
{
|
||||
Console.Write(result[i][j] + " ");
|
||||
}
|
||||
Console.WriteLine();
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,10 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
@@ -1,24 +0,0 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.5.2.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FindDiagonalOrder", "FindDiagonalOrder.csproj", "{B3151728-C057-4305-DD4C-9A2AFBFC189A}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{B3151728-C057-4305-DD4C-9A2AFBFC189A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{B3151728-C057-4305-DD4C-9A2AFBFC189A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B3151728-C057-4305-DD4C-9A2AFBFC189A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B3151728-C057-4305-DD4C-9A2AFBFC189A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {DB56539A-6F32-4D28-B91F-BB1DCF46F4D0}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
@@ -1,10 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
@@ -1,61 +0,0 @@
|
||||
public class Solution {
|
||||
public int[] FindDiagonalOrder(int[][] mat)
|
||||
{
|
||||
if (mat == null || mat.Length == 0 || mat[0].Length == 0)
|
||||
{
|
||||
return new int[0];
|
||||
}
|
||||
|
||||
var m = mat.Length;
|
||||
var n = mat[0].Length;
|
||||
|
||||
var diagonals = new Dictionary<int, List<int>>();
|
||||
|
||||
for (var i = 0; i < m; i++)
|
||||
{
|
||||
for (var j = 0; j < n; j++)
|
||||
{
|
||||
int diagonalIndex = i + j;
|
||||
if (!diagonals.ContainsKey(diagonalIndex))
|
||||
{
|
||||
diagonals[diagonalIndex] = new List<int>();
|
||||
}
|
||||
diagonals[diagonalIndex].Add(mat[i][j]);
|
||||
}
|
||||
}
|
||||
|
||||
var result = new List<int>();
|
||||
foreach (var key in diagonals.Keys)
|
||||
{
|
||||
var diagonal = diagonals[key];
|
||||
if (key % 2 == 0)
|
||||
{
|
||||
result.AddRange(diagonal);
|
||||
}
|
||||
else
|
||||
{
|
||||
diagonal.Reverse();
|
||||
result.AddRange(diagonal);
|
||||
}
|
||||
}
|
||||
|
||||
return result.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
class Program
|
||||
{
|
||||
static void Main()
|
||||
{
|
||||
var Solution = new Solution();
|
||||
|
||||
int[][] mat1 = new int[][]{
|
||||
new int[]{1,2,3},
|
||||
new int[]{4,5,6},
|
||||
new int[]{7,8,9}
|
||||
};
|
||||
|
||||
Console.WriteLine(string.Join(", ", Solution.FindDiagonalOrder(mat1)));
|
||||
|
||||
}
|
||||
}
|
@@ -1,45 +0,0 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func findDiagonalOrder(mat [][]int) []int {
|
||||
if len(mat) == 0 || len(mat[0]) == 0{
|
||||
return []int{}
|
||||
}
|
||||
|
||||
m := len(mat)
|
||||
n := len(mat[0])
|
||||
|
||||
// maps
|
||||
diagonals := make(map[int][]int)
|
||||
|
||||
for i:=0; i< m;i++{
|
||||
for j:=0; j < n; j++{
|
||||
index := i+j
|
||||
diagonals[index] = append(diagonals[index], mat[i][j])
|
||||
}
|
||||
}
|
||||
|
||||
result := []int{}
|
||||
|
||||
for i:= 0; i< m+n-1; i++{
|
||||
if i% 2 == 0{
|
||||
reverse(diagonals[i])
|
||||
result = append(result, diagonals[i]...)
|
||||
}else{
|
||||
result = append(result, diagonals[i]...)
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func reverse(slice []int){
|
||||
left, right :=0, len(slice)-1
|
||||
|
||||
for left < right{
|
||||
slice[left], slice[right] = slice[right], slice[left]
|
||||
left++
|
||||
right--
|
||||
}
|
||||
}
|
@@ -1,7 +0,0 @@
|
||||
1. 觀察矩陣對角線模式
|
||||
1. (0,0) -> 1 -> i+j = 0
|
||||
2. (1, 0), (0, 1) -> 2 -> i+j = 1
|
||||
3. (2, 0), (1, 1), (0, 2) -> 3 -> i+j = 2
|
||||
2. how to deal with diagonal sorting?
|
||||
1. while (i+j) % 2 == 1
|
||||
2. while (i+j) % 2 == 0 reversed
|
@@ -1,24 +0,0 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.5.2.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "soupServings", "soupServings.csproj", "{6D960F00-6A53-6E19-86A1-4BF3D1CD764F}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{6D960F00-6A53-6E19-86A1-4BF3D1CD764F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{6D960F00-6A53-6E19-86A1-4BF3D1CD764F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{6D960F00-6A53-6E19-86A1-4BF3D1CD764F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{6D960F00-6A53-6E19-86A1-4BF3D1CD764F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {11CC27B7-C17E-4820-8A68-ADD32A2B37F8}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
@@ -1,56 +0,0 @@
|
||||
using System;
|
||||
|
||||
public class Solution
|
||||
{
|
||||
private Dictionary<(int, int), double> dp = new Dictionary<(int, int), double>();
|
||||
public double SoupServings(int n)
|
||||
{
|
||||
if (n > 5000)
|
||||
return 1.0;
|
||||
|
||||
n = (n + 24) / 25;
|
||||
|
||||
// use dynamic programming
|
||||
return Helper(n, n);
|
||||
}
|
||||
|
||||
private double Helper(int a, int b)
|
||||
{
|
||||
if (a <= 0 && b <= 0)
|
||||
{
|
||||
return 0.5;
|
||||
}
|
||||
if (a <= 0)
|
||||
{
|
||||
return 1.0;
|
||||
}
|
||||
if (b <= 0)
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
if (dp.ContainsKey((a, b)))
|
||||
{
|
||||
return dp[(a, b)];
|
||||
}
|
||||
|
||||
double probability = 0.25 * (
|
||||
Helper(a - 4, b) +
|
||||
Helper(a - 3, b - 1) +
|
||||
Helper(a - 2, b - 2) +
|
||||
Helper(a - 1, b - 3)
|
||||
);
|
||||
|
||||
dp[(a, b)] = probability;
|
||||
return probability;
|
||||
}
|
||||
}
|
||||
|
||||
class Program
|
||||
{
|
||||
static void Main()
|
||||
{
|
||||
var Solution = new Solution();
|
||||
var ans = Solution.SoupServings(800);
|
||||
Console.WriteLine(ans);
|
||||
}
|
||||
}
|
@@ -1,10 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
@@ -1,52 +0,0 @@
|
||||
package main
|
||||
|
||||
import ("fmt")
|
||||
|
||||
type Solution struct{
|
||||
dp map[[2]int]float64
|
||||
}
|
||||
|
||||
func NewSolution() *Solution{
|
||||
return &Solution{dp: make(map[[2]int]float64)}
|
||||
}
|
||||
|
||||
func (s *Solution) SoupServings(n int)float64{
|
||||
if n > 5000{
|
||||
return 1.0
|
||||
}
|
||||
|
||||
n = (n+24) /25
|
||||
|
||||
return s.helper(n, n)
|
||||
}
|
||||
|
||||
func (s * Solution) helper(a, b int) float64 {
|
||||
if a <= 0 && b <= 0{
|
||||
return 0.5
|
||||
}
|
||||
if a <= 0{
|
||||
return 1.0
|
||||
}
|
||||
if b <= 0{
|
||||
return 0
|
||||
}
|
||||
|
||||
if val, exist := s.dp[[2]int{a, b}]; exist{
|
||||
return val
|
||||
}
|
||||
|
||||
probability := 0.25 * (
|
||||
s.helper(a-4, b) +
|
||||
s.helper(a-3, b-1) +
|
||||
s.helper(a-2, b-2) +
|
||||
s.helper(a-1, b-3))
|
||||
|
||||
s.dp[[2]int {a, b}] = probability
|
||||
return probability
|
||||
}
|
||||
|
||||
func main(){
|
||||
Solution := NewSolution()
|
||||
ans := Solution.SoupServings(100)
|
||||
fmt.Println(ans)
|
||||
}
|
@@ -1,14 +0,0 @@
|
||||
You have two soups, A and B, each starting with n mL. On every turn, one of the following four serving operations is chosen at random, each with probability 0.25 independent of all previous turns:
|
||||
|
||||
pour 100 mL from type A and 0 mL from type B
|
||||
pour 75 mL from type A and 25 mL from type B
|
||||
pour 50 mL from type A and 50 mL from type B
|
||||
pour 25 mL from type A and 75 mL from type B
|
||||
Note:
|
||||
|
||||
There is no operation that pours 0 mL from A and 100 mL from B.
|
||||
The amounts from A and B are poured simultaneously during the turn.
|
||||
If an operation asks you to pour more than you have left of a soup, pour all that remains of that soup.
|
||||
The process stops immediately after any turn in which one of the soups is used up.
|
||||
|
||||
Return the probability that A is used up before B, plus half the probability that both soups are used up in the same turn. Answers within 10-5 of the actual answer will be accepted.
|
@@ -16,6 +16,8 @@
|
||||
| 日期 | 題目 | 難度 | 語言 | 耗時 | 狀態 | 心得 |
|
||||
|------|------|------|------|------|------|------|
|
||||
| 09/08 | Convert Integer To The Sum Of Two No Zero Integers | Easy | C# | 0.2hr | Done | |
|
||||
| 09/11 | Sort Vowels In A String | Medium | C# | 0.2hr | Done | |
|
||||
| 09/11 | [3227]Vowels Game In A String | Medium | C#, go | 0.1hr | Done | like easy |
|
||||
|
||||
### Week 3
|
||||
| 日期 | 題目 | 難度 | 語言 | 耗時 | 狀態 | 心得 |
|
||||
@@ -25,18 +27,19 @@
|
||||
### Week 4
|
||||
| 日期 | 題目 | 難度 | 語言 | 耗時 | 狀態 | 心得 |
|
||||
|------|------|------|------|------|------|------|
|
||||
| | | | | | | |
|
||||
| 09/22 | [3005]Count Elements With Maximum Frequency | Easy | C# | 0.3hr | Done | Dictionary Mapping |
|
||||
| 09/23| [0165]Compare Version Numbers | Medium | C# | 0.4hr | Done | String, Two Pointers |
|
||||
|
||||
## 📈 本月統計
|
||||
|
||||
### 完成情況
|
||||
- **總練習天數**: 6 天
|
||||
- **完成題數**: 6題
|
||||
- **語言分布**: C# 6(題), Go 2(題)
|
||||
- **難度分布**: Easy 2(題), Medium 3(題), Hard 1(題)
|
||||
- **總練習天數**: 9 天
|
||||
- **完成題數**: 9題
|
||||
- **語言分布**: C# 9(題), Go 2(題)
|
||||
- **難度分布**: Easy 3(題), Medium 5(題), Hard 1(題)
|
||||
|
||||
### 時間投入
|
||||
- **總時間**: 3.7小時
|
||||
- **總時間**: 4.5小時
|
||||
- **平均每題**: 分鐘
|
||||
- **每日平均**: 分鐘
|
||||
|
||||
@@ -44,6 +47,7 @@
|
||||
|
||||
### 新掌握的技巧
|
||||
1. 貪心策略
|
||||
2. string轉char, char轉string
|
||||
|
||||
### 常犯錯誤分析
|
||||
1.
|
||||
|
@@ -83,4 +83,102 @@
|
||||
> "演算法不是背出來的,是理解出來的" - 在第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
99
logs/2025-11.md
Normal 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/效能注意點/測試習慣
|
||||
- Go:slice/map/指標/錯誤處理/benchmark 習慣
|
||||
|
||||
## 🔄 困難案例復盤
|
||||
|
||||
### 案例1:題號/主題
|
||||
- 問題:
|
||||
- 嘗試:
|
||||
- 解決:
|
||||
- 學習:
|
||||
|
||||
### 案例2:題號/主題
|
||||
- 問題:
|
||||
- 嘗試:
|
||||
- 解決:
|
||||
- 學習:
|
||||
|
||||
## 📝 下月計畫
|
||||
- 目標題數:
|
||||
- 重點主題:
|
||||
- 練習節奏:
|
||||
- 要避免的坑:
|
||||
|
||||
## 💡 本月金句
|
||||
>
|
||||
|
||||
---
|
||||
**總結**:本月最大收穫是 ______,接下來專注 ______。
|
||||
|
99
logs/2025-12.md
Normal file
99
logs/2025-12.md
Normal 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/效能注意點/測試習慣
|
||||
- Go:slice/map/指標/錯誤處理/benchmark 習慣
|
||||
|
||||
## 🔄 困難案例復盤
|
||||
|
||||
### 案例1:題號/主題
|
||||
- 問題:
|
||||
- 嘗試:
|
||||
- 解決:
|
||||
- 學習:
|
||||
|
||||
### 案例2:題號/主題
|
||||
- 問題:
|
||||
- 嘗試:
|
||||
- 解決:
|
||||
- 學習:
|
||||
|
||||
## 📝 下月計畫
|
||||
- 目標題數:
|
||||
- 重點主題:
|
||||
- 練習節奏:
|
||||
- 要避免的坑:
|
||||
|
||||
## 💡 本月金句
|
||||
>
|
||||
|
||||
---
|
||||
**總結**:本月最大收穫是 ______,接下來專注 ______。
|
||||
|
22
makefile
Normal file
22
makefile
Normal file
@@ -0,0 +1,22 @@
|
||||
# Makefile - 安裝環境工具
|
||||
|
||||
.PHONY: all update upgrade install setup check
|
||||
|
||||
all: setup
|
||||
|
||||
update:
|
||||
sudo apt update
|
||||
|
||||
upgrade:
|
||||
sudo apt upgrade -y
|
||||
|
||||
install:
|
||||
sudo apt install -y dotnet-sdk-8.0 golang-go
|
||||
|
||||
setup: update upgrade install check
|
||||
@echo "✅ 開發環境安裝完成!"
|
||||
|
||||
check:
|
||||
@echo "=== 檢查安裝結果 ==="
|
||||
@dotnet --version || echo "⚠️ dotnet 未安裝成功"
|
||||
@go version || echo "⚠️ go 未安裝成功"
|
85
problems/0165-compare-version-numbers/README.md
Normal file
85
problems/0165-compare-version-numbers/README.md
Normal file
@@ -0,0 +1,85 @@
|
||||
# [165] Compare Version Numbers
|
||||
|
||||
## 題目資訊
|
||||
- **難度**: Medium
|
||||
- **標籤**: Two Pointer, String
|
||||
- **題目連結**: https://leetcode.com/problems/compare-version-numbers/
|
||||
- **練習日期**: 2025-09-23
|
||||
- **目標複雜度**: 時間 O(n)、空間 O(1)
|
||||
|
||||
## 題目描述
|
||||
Given two **version strings**, `version1` and `version2`, compare them. A version string consists of **revisions** separated by dots `'.'`. The **value of the revision** is its **integer conversion** ignoring leading zeros.
|
||||
|
||||
To compare version strings, compare their revision values in **left-to-right order**. If one of the version strings has fewer revisions, treat the missing revision values as `0`.
|
||||
|
||||
Return the following:
|
||||
|
||||
If `version1 < version2`, return -1.
|
||||
If `version1 > version2`, return 1.
|
||||
Otherwise, return 0.
|
||||
|
||||
## 先備條件與限制
|
||||
- 1 <= `version1.length, version2.length` <= 500
|
||||
- version1 and version2 only contain digits and '.'
|
||||
- version1 and version2 are valid version numbers.
|
||||
- All the given revisions in `version1` and `version2` can be stored in a **32-bit integer**
|
||||
|
||||
## 解題思路
|
||||
|
||||
### 初步分析
|
||||
- 類型:字串雙指標掃描
|
||||
- 關鍵觀察:版本號可以逐段比較,缺段視為 0,且修訂號只包含數字
|
||||
- 複雜度目標理由:只需線性掃過兩個字串一次即可完成比較
|
||||
|
||||
### 解法比較
|
||||
1. 解法A(基準/暴力):
|
||||
- 名稱:`MyCompareVersion`
|
||||
- 思路:以 `Split('.')` 將版本字串拆成陣列,逐段轉成整數後比較;若另一側段數不足以 0 補齊
|
||||
- 正確性:LeetCode 限制每段可裝進 32-bit 整數,直接使用 `int.TryParse` 安全可靠
|
||||
- 複雜度:時間 O(n),空間 O(k)(k 為段數,需配置字串陣列與子字串)
|
||||
2. 解法B(優化):
|
||||
- 名稱:`CompareVersion`
|
||||
- 思路:雙指標同步掃描兩個版本字串,藉由 `ReadOnlySpan<char>` 抓取下一段,去除前導 0 後用字元比較避免溢位與額外配置
|
||||
- 正確性:段長先比較、再逐字比較,完全符合題意;缺段會回傳空 span 視為 0
|
||||
- 複雜度:時間 O(n),空間 O(1)
|
||||
|
||||
## 實作細節
|
||||
|
||||
### 常見陷阱
|
||||
- 前導 0:需在比較前移除,否則 `"01"` 與 `"1"` 會被視為不同
|
||||
- 段數不一致:右側缺少的段要視為 0
|
||||
- 空字串或末尾點:`""`、`"1."` 都可能出現,需要妥善處理
|
||||
- 非數字字元:防守性處理(當前實作視為 0),但依題意實際資料不會出現
|
||||
|
||||
## 測試案例
|
||||
|
||||
### 範例輸入輸出
|
||||
```
|
||||
Input: version1 = "1.2", version2 = "1.10"
|
||||
Output: -1
|
||||
Explanation:
|
||||
version1's second revision is "2" and version2's second revision is "10": 2 < 10, so version1 < version2.
|
||||
```
|
||||
|
||||
### 邊界清單
|
||||
- [x] 空字串 / 僅有 0
|
||||
- [x] 單一段 / 全相同
|
||||
- [x] 含 0 / 大數 / 前導 0
|
||||
- [ ] 去重(與此題無關)
|
||||
- [x] 大資料壓力(長度 200 的版本字串)
|
||||
|
||||
## 複雜度分析
|
||||
- 最壞:時間 O(n)、空間 O(1)
|
||||
- 備註:保留的 `MyCompareVersion` 雖然同為 O(n),但空間為 O(k)
|
||||
|
||||
## 相關題目 / Follow-up
|
||||
- 179. Largest Number:同樣涉及字串排序與比較
|
||||
- 415. Add Strings:字串逐位操作
|
||||
|
||||
## 學習筆記
|
||||
- 今天學到:兩指標搭配 `ReadOnlySpan<char>` 可以在 C# 中避免額外配置
|
||||
- 卡住與修正:原本 console app 移除 `Main` 造成 `dotnet test` 無法編譯,後來補回精簡入口
|
||||
- 待優化:若要支援超長版本段,可考慮使用 `BigInteger` 或自訂比較邏輯(目前已以字元比較處理)
|
||||
|
||||
---
|
||||
**總結**:核心在於逐段處理並正確處理前導 0 與缺段情況,適合練習字串雙指標與記憶體優化技巧。
|
144
problems/0165-compare-version-numbers/csharp/Program.cs
Normal file
144
problems/0165-compare-version-numbers/csharp/Program.cs
Normal file
@@ -0,0 +1,144 @@
|
||||
// LeetCode 165: Compare Version Numbers
|
||||
// 難度: Medium
|
||||
// 日期: 2025-09-23
|
||||
|
||||
using System;
|
||||
|
||||
public class Solution
|
||||
{
|
||||
// Two-pointer parser that compares segments without allocating intermediate arrays.
|
||||
public int CompareVersion(string version1, string version2)
|
||||
{
|
||||
var i = 0;
|
||||
var j = 0;
|
||||
|
||||
while (i < version1.Length || j < version2.Length)
|
||||
{
|
||||
var segment1 = NextSegment(version1, ref i);
|
||||
var segment2 = NextSegment(version2, ref j);
|
||||
|
||||
var comparison = CompareSegments(segment1, segment2);
|
||||
if (comparison != 0)
|
||||
{
|
||||
return comparison;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Reads the next numeric segment (between dots) as a span and advances the current index.
|
||||
private static ReadOnlySpan<char> NextSegment(string version, ref int index)
|
||||
{
|
||||
if (index >= version.Length)
|
||||
{
|
||||
return ReadOnlySpan<char>.Empty;
|
||||
}
|
||||
|
||||
var start = index;
|
||||
while (index < version.Length && version[index] != '.')
|
||||
{
|
||||
index++;
|
||||
}
|
||||
|
||||
var segment = version.AsSpan(start, index - start);
|
||||
|
||||
if (index < version.Length && version[index] == '.')
|
||||
{
|
||||
index++;
|
||||
}
|
||||
|
||||
return segment;
|
||||
}
|
||||
|
||||
// Compares two trimmed segments lexicographically to avoid integer overflow.
|
||||
private static int CompareSegments(ReadOnlySpan<char> left, ReadOnlySpan<char> right)
|
||||
{
|
||||
left = TrimLeadingZeros(left);
|
||||
right = TrimLeadingZeros(right);
|
||||
|
||||
if (left.Length > right.Length)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (left.Length < right.Length)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (var i = 0; i < left.Length; i++)
|
||||
{
|
||||
if (left[i] > right[i])
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (left[i] < right[i])
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static ReadOnlySpan<char> TrimLeadingZeros(ReadOnlySpan<char> segment)
|
||||
{
|
||||
var index = 0;
|
||||
while (index < segment.Length && segment[index] == '0')
|
||||
{
|
||||
index++;
|
||||
}
|
||||
|
||||
return index == segment.Length ? ReadOnlySpan<char>.Empty : segment[index..];
|
||||
}
|
||||
|
||||
public int MyCompareVersion(string version1, string version2)
|
||||
{
|
||||
var v1 = version1.Split('.');
|
||||
var v2 = version2.Split('.');
|
||||
|
||||
if (v1.Length >= v2.Length)
|
||||
{
|
||||
return CompareString(v1, v2);
|
||||
}
|
||||
|
||||
return CompareString(v2, v1) * -1;
|
||||
}
|
||||
|
||||
private static int CompareString(string[] longer, string[] shorter)
|
||||
{
|
||||
for (var i = 0; i < longer.Length; i++)
|
||||
{
|
||||
_ = int.TryParse(longer[i], out var num1);
|
||||
var num2 = i < shorter.Length && int.TryParse(shorter[i], out var parsed) ? parsed : 0;
|
||||
|
||||
if (num1 > num2)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (num1 < num2)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
// optional: keep console app functional for manual verification
|
||||
if (args.Length == 2)
|
||||
{
|
||||
var solution = new Solution();
|
||||
var result = solution.CompareVersion(args[0], args[1]);
|
||||
Console.WriteLine(result);
|
||||
}
|
||||
}
|
||||
}
|
5
legacy/2438 ProductQueries/C#/ProductQueries.csproj → problems/0165-compare-version-numbers/csharp/csharp.csproj
Executable file → Normal file
5
legacy/2438 ProductQueries/C#/ProductQueries.csproj → problems/0165-compare-version-numbers/csharp/csharp.csproj
Executable file → Normal file
@@ -1,10 +1,9 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
|
56
problems/0165-compare-version-numbers/test/SolutionTests.cs
Normal file
56
problems/0165-compare-version-numbers/test/SolutionTests.cs
Normal file
@@ -0,0 +1,56 @@
|
||||
// LeetCode 165: Compare Version Numbers 單元測試(xUnit)
|
||||
|
||||
using System.Linq;
|
||||
using Xunit;
|
||||
|
||||
public class SolutionTests {
|
||||
private readonly Solution _s = new Solution();
|
||||
|
||||
[Theory]
|
||||
[InlineData("1.01", "1.001", 0)]
|
||||
[InlineData("1.0", "1.0.0", 0)]
|
||||
[InlineData("1.0.0.0", "1", 0)]
|
||||
[InlineData("0.1", "1.1", -1)]
|
||||
[InlineData("1.0.1", "1", 1)]
|
||||
[InlineData("7.5.2.4", "7.5.3", -1)]
|
||||
public void CompareVersion_ReturnsExpectedResult(string version1, string version2, int expected) {
|
||||
var actual = _s.CompareVersion(version1, version2);
|
||||
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("1.0.1", "1")]
|
||||
[InlineData("3.0.0", "2.9.9.9")]
|
||||
[InlineData("10.4", "10.3.9")]
|
||||
public void CompareVersion_IsAntiSymmetric(string left, string right) {
|
||||
var forward = _s.CompareVersion(left, right);
|
||||
var backward = _s.CompareVersion(right, left);
|
||||
|
||||
Assert.Equal(1, forward);
|
||||
Assert.Equal(-1, backward);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("", "", 0)]
|
||||
[InlineData("", "0", 0)]
|
||||
[InlineData("0.0.0", "", 0)]
|
||||
[InlineData("000", "0", 0)]
|
||||
[InlineData("2147483647", "2147483646", 1)]
|
||||
[InlineData("2147483646", "2147483647", -1)]
|
||||
public void CompareVersion_HandlesBoundaryInputs(string version1, string version2, int expected) {
|
||||
var actual = _s.CompareVersion(version1, version2);
|
||||
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CompareVersion_LongSequencesDifferAtEnd() {
|
||||
var left = string.Join('.', Enumerable.Repeat("0", 199).Append("1"));
|
||||
var right = string.Join('.', Enumerable.Repeat("0", 200));
|
||||
|
||||
var result = _s.CompareVersion(left, right);
|
||||
|
||||
Assert.Equal(1, result);
|
||||
}
|
||||
}
|
@@ -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>
|
||||
|
29
problems/0165-compare-version-numbers/test/edge_cases.md
Normal file
29
problems/0165-compare-version-numbers/test/edge_cases.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# 邊界情況清單(165 Compare Version Numbers)
|
||||
|
||||
## 需要測試的邊界
|
||||
- [x] 空輸入 / 單一元素:`""`、`"0"`
|
||||
- [x] 重複元素 / 全相同:`"1.0.0"` vs `"1"`
|
||||
- [x] 極值(最小/最大):`"2147483647"` vs `"2147483646"`
|
||||
- [x] 含負數 / 0 / 大數:題目無負數,已覆蓋多零與大修訂號
|
||||
- [x] 大資料量(接近上限):200 段版本字串
|
||||
|
||||
## 額外案例
|
||||
### 案例 1
|
||||
- 輸入:`version1 = "", version2 = "0"`
|
||||
- 預期:`0`
|
||||
- 說明:空字串缺少所有段,視為全 0
|
||||
|
||||
### 案例 2
|
||||
- 輸入:`version1 = "2147483647", version2 = "2147483646"`
|
||||
- 預期:`1`
|
||||
- 說明:驗證最大 32-bit 整數段處理
|
||||
|
||||
### 案例 3
|
||||
- 輸入:`version1 = "0.0.0", version2 = "0"`
|
||||
- 預期:`0`
|
||||
- 說明:多段全 0 與單段 0 視為相同
|
||||
|
||||
### 案例 4
|
||||
- 輸入:`version1 = string.Join(".", Enumerable.Repeat("0", 199)) + ".1"`, `version2 = string.Join(".", Enumerable.Repeat("0", 200))`
|
||||
- 預期:`1`
|
||||
- 說明:長度 200 的版本字串,在最後一段差異才分勝負
|
@@ -0,0 +1,30 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.5.2.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "csharp", "csharp\csharp.csproj", "{CF022C7B-CAF3-706D-67E1-FB93518229B7}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestProject", "test\TestProject.csproj", "{C670389A-9CE7-B456-51E5-A79D56E199CF}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{CF022C7B-CAF3-706D-67E1-FB93518229B7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{CF022C7B-CAF3-706D-67E1-FB93518229B7}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{CF022C7B-CAF3-706D-67E1-FB93518229B7}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{CF022C7B-CAF3-706D-67E1-FB93518229B7}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{C670389A-9CE7-B456-51E5-A79D56E199CF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C670389A-9CE7-B456-51E5-A79D56E199CF}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C670389A-9CE7-B456-51E5-A79D56E199CF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C670389A-9CE7-B456-51E5-A79D56E199CF}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {C5790EDA-C36F-4FC3-877D-C7E20837E160}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
80
problems/0166-fraction-to-recurring-decimal/README.md
Normal file
80
problems/0166-fraction-to-recurring-decimal/README.md
Normal file
@@ -0,0 +1,80 @@
|
||||
# [166] Fraction To Recurring Decimal
|
||||
|
||||
## 題目資訊
|
||||
- **難度**: Medium
|
||||
- **標籤**: Hash Table, Math, Simulation
|
||||
- **題目連結**: https://leetcode.com/problems/fraction-to-recurring-decimal/
|
||||
- **練習日期**: 2025-09-24
|
||||
- **目標複雜度**: 時間 O(L)、空間 O(L)(L 為輸出字串長度,最多 10^4)
|
||||
|
||||
## 題目描述
|
||||
Given two integers representing the `numerator` and `denominator` of a fraction, return *the fraction* in string format.
|
||||
|
||||
If the fractional part is repeating, enclose the repeating part in parentheses.
|
||||
|
||||
If multiple answers are possible, return **any of them**.
|
||||
|
||||
It is **guaranteed** that the length of the answer string is less than `10^4` for all the given inputs.
|
||||
|
||||
## 先備條件與限制
|
||||
- 輸入限制:`-2^31 <= numerator, denominator <= 2^31 - 1`,且 denominator ≠ 0
|
||||
- 回傳/輸出格式:回傳十進位字串;有限小數直接輸出,小數有循環時用括號標記循環段
|
||||
- 其他:允許使用 64-bit 以避免在取絕對值時溢位
|
||||
|
||||
## 解題思路
|
||||
|
||||
### 初步分析
|
||||
- 類型:數學 / 模擬 / 哈希
|
||||
- 關鍵觀察:整數除法僅靠餘數決定下一個小數位;相同餘數必定導致循環,位置可透過哈希表還原
|
||||
- 複雜度目標理由:每個餘數最多處理一次,因此時間與空間成正比於輸出長度 L
|
||||
|
||||
### 解法比較
|
||||
1. 解法A:餘數位置哈希
|
||||
- 思路:先處理正負號並計算整數部分;對小數部分反覆以 10 乘上餘數取商,並在 map 中紀錄餘數首次出現的索引,一旦重複即可插入括號
|
||||
- 正確性:每個可能的餘數介於 0 與 |denominator|-1,重複時即代表循環節開始,未重複則最後餘數為 0(有限小數)
|
||||
- 複雜度:時間 O(L) / 空間 O(L)
|
||||
|
||||
## 實作細節
|
||||
- 先處理 `numerator == 0` 直接回傳 "0"
|
||||
- 判斷結果正負號,使用 `long`/`long long` 取絕對值避免 `INT_MIN` 無法轉正的問題
|
||||
- `integer_part = abs_num / abs_den` 直接加入結果,小數部分以餘數 `remainder = abs_num % abs_den` 開始
|
||||
- 使用字典 `remainder -> index` 紀錄餘數在結果字串中的位置;迴圈內:餘數乘 10,取下一位商並更新餘數
|
||||
- 若餘數為 0,表示小數結束,不需括號;若餘數再度出現,在對應索引插入 `(`,在結尾加 `)`
|
||||
|
||||
## 常見陷阱
|
||||
- 處理負數:符號只出現一次,判斷後用 64-bit 絕對值繼續運算避免 `--6...` 之類錯誤
|
||||
- `INT_MIN / -1` 可能溢位:需先轉成 64-bit 再做除法與取餘數
|
||||
- 餘數 map 要記錄的是「餘數出現時的輸出索引」,找到重複時要在該位置插入 `(`
|
||||
- 每回合先檢查餘數是否重複再乘 10,避免多插一位或落掉循環起點
|
||||
- `numerator` 為 0 時無小數部分,直接回傳 "0"
|
||||
|
||||
## 測試案例
|
||||
|
||||
### 範例輸入輸出
|
||||
```
|
||||
Input: numerator = 4, denominator = 333
|
||||
Output: "0.(012)"
|
||||
```
|
||||
|
||||
### 邊界清單
|
||||
- `numerator = 1, denominator = 2` → `"0.5"`(有限小數)
|
||||
- `numerator = 1, denominator = 6` → `"0.1(6)"`(循環節不從第一位開始)
|
||||
- `numerator = -50, denominator = 8` → `"-6.25"`(負數與有限小數)
|
||||
- `numerator = 0, denominator = 5` → `"0"`(整數結果)
|
||||
- `numerator = 1, denominator = 7` → `"0.(142857)"`(較長的循環節)
|
||||
|
||||
## 複雜度分析
|
||||
- 最壞:時間 O(L)、空間 O(L)
|
||||
- L 為輸出字串長度,等同於需要處理的餘數數量上限(題目保證 < 10^4)
|
||||
|
||||
## 相關題目 / Follow-up
|
||||
- 與任一進位制的循環小數檢測(如 base conversion)類似,可類比餘數循環檢測技巧
|
||||
|
||||
## 學習筆記
|
||||
- 今天學到:餘數 → 索引的哈希表能精準標記循環段,搭配 `StringBuilder.Insert` 可快速加括號
|
||||
- 卡住與修正:`int.MinValue` 轉正時會拋例外,改用 `long` 做完整流程(含乘 10 與取餘)就穩定
|
||||
- 另外注意:符號在輸出開頭先處理,整數和小數部分都用正數運算可避免重複符號
|
||||
- 待優化:可以先行預估非循環長度以減少插入成本,但對此題影響不大
|
||||
|
||||
---
|
||||
**總結**:這題的核心在於以餘數哈希判斷循環節,適合練習小數表示與溢位處理。
|
@@ -0,0 +1,68 @@
|
||||
// LeetCode 166: Fraction To Recurring Decimal
|
||||
// 難度: Medium
|
||||
// 日期: 2025-09-24
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
public class Solution
|
||||
{
|
||||
public string FractionToDecimal(int numerator, int denominator)
|
||||
{
|
||||
if (numerator == 0) return "0";
|
||||
|
||||
long num = numerator;
|
||||
long den = denominator;
|
||||
|
||||
StringBuilder result = new StringBuilder();
|
||||
bool isNegative = (num < 0) ^ (den < 0);
|
||||
if (isNegative) result.Append('-');
|
||||
|
||||
num = Math.Abs(num);
|
||||
den = Math.Abs(den);
|
||||
|
||||
long integerPart = num / den;
|
||||
result.Append(integerPart);
|
||||
|
||||
long remainder = num % den;
|
||||
if (remainder == 0) return result.ToString();
|
||||
|
||||
result.Append('.');
|
||||
result.Append(CalculateDecimalPart(remainder, den));
|
||||
|
||||
return result.ToString();
|
||||
}
|
||||
|
||||
private string CalculateDecimalPart(long remainder, long denominator)
|
||||
{
|
||||
StringBuilder decimalBuilder = new StringBuilder();
|
||||
Dictionary<long, int> remainderMap = new Dictionary<long, int>();
|
||||
|
||||
while (remainder != 0)
|
||||
{
|
||||
if (remainderMap.TryGetValue(remainder, out int repeatIndex))
|
||||
{
|
||||
decimalBuilder.Insert(repeatIndex, '(');
|
||||
decimalBuilder.Append(')');
|
||||
break;
|
||||
}
|
||||
|
||||
remainderMap[remainder] = decimalBuilder.Length;
|
||||
remainder *= 10;
|
||||
long digit = remainder / denominator;
|
||||
decimalBuilder.Append(digit);
|
||||
remainder %= denominator;
|
||||
}
|
||||
|
||||
return decimalBuilder.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public class Program {
|
||||
public static void Main() {
|
||||
var s = new Solution();
|
||||
|
||||
}
|
||||
}
|
5
legacy/2787 numberOfWays/C#/numberOfWays.csproj → problems/0166-fraction-to-recurring-decimal/csharp/csharp.csproj
Executable file → Normal file
5
legacy/2787 numberOfWays/C#/numberOfWays.csproj → problems/0166-fraction-to-recurring-decimal/csharp/csharp.csproj
Executable file → Normal file
@@ -1,10 +1,9 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
|
3
problems/0166-fraction-to-recurring-decimal/go/go.mod
Normal file
3
problems/0166-fraction-to-recurring-decimal/go/go.mod
Normal file
@@ -0,0 +1,3 @@
|
||||
module leetcode-166
|
||||
|
||||
go 1.18
|
18
problems/0166-fraction-to-recurring-decimal/go/main.go
Normal file
18
problems/0166-fraction-to-recurring-decimal/go/main.go
Normal file
@@ -0,0 +1,18 @@
|
||||
// LeetCode 166: Fraction To Recurring Decimal
|
||||
// 難度: Medium
|
||||
// 日期: 2025-09-24
|
||||
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
// TODO: 根據題意調整簽名
|
||||
func solve(nums []int) int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func main() {
|
||||
fmt.Printf("Hello LeetCode 166!\n")
|
||||
// TODO: 可加入簡單測試
|
||||
}
|
||||
|
@@ -0,0 +1,27 @@
|
||||
// LeetCode 166 單元測試(xUnit)
|
||||
|
||||
using Xunit;
|
||||
|
||||
public class SolutionTests {
|
||||
private readonly Solution _s = new Solution();
|
||||
|
||||
[Theory]
|
||||
[InlineData(4, 333, "0.(012)")]
|
||||
[InlineData(1, 2, "0.5")]
|
||||
[InlineData(1, 6, "0.1(6)")]
|
||||
[InlineData(-50, 8, "-6.25")]
|
||||
[InlineData(0, 5, "0")]
|
||||
[InlineData(1, 7, "0.(142857)")]
|
||||
public void FractionToDecimal_BasicAndRepeatingScenarios(int numerator, int denominator, string expected) {
|
||||
var actual = _s.FractionToDecimal(numerator, denominator);
|
||||
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FractionToDecimal_DenominatorOne_ReturnsIntegerString() {
|
||||
var actual = _s.FractionToDecimal(2, 1);
|
||||
|
||||
Assert.Equal("2", actual);
|
||||
}
|
||||
}
|
@@ -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>
|
||||
|
@@ -0,0 +1,20 @@
|
||||
# 邊界情況清單(166 Fraction To Recurring Decimal)
|
||||
|
||||
## 需要測試的邊界
|
||||
- [ ] 空輸入 / 單一元素
|
||||
- [ ] 重複元素 / 全相同
|
||||
- [ ] 極值(最小/最大)
|
||||
- [ ] 含負數 / 0 / 大數
|
||||
- [ ] 大資料量(接近上限)
|
||||
|
||||
## 額外案例
|
||||
### 案例 1
|
||||
- 輸入:
|
||||
- 預期:
|
||||
- 說明:
|
||||
|
||||
### 案例 2
|
||||
- 輸入:
|
||||
- 預期:
|
||||
- 說明:
|
||||
|
@@ -0,0 +1,12 @@
|
||||
// LeetCode 166 單元測試(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) }
|
||||
}
|
||||
|
@@ -1,21 +0,0 @@
|
||||
#!/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 ""
|
||||
echo "📊 測試完成!"
|
70
problems/2785-sort-vowels-in-a-string/README.md
Normal file
70
problems/2785-sort-vowels-in-a-string/README.md
Normal file
@@ -0,0 +1,70 @@
|
||||
# [2785] Sort Vowels In A String
|
||||
|
||||
## 題目資訊
|
||||
- **難度**: Medium
|
||||
- **標籤**: String, Sorting
|
||||
- **題目連結**: [LeetCode](https://leetcode.com/problems/sort-vowels-in-a-string/)
|
||||
- **練習日期**: 2025-09-11
|
||||
|
||||
## 題目描述
|
||||
給定一個 0-indexed 的字串 s,重新排列 s 以獲得新字串 t,使得:
|
||||
|
||||
所有子音保持在原來的位置
|
||||
母音必須按照 ASCII 值的非遞減順序排序
|
||||
|
||||
更正式地說:
|
||||
|
||||
如果存在索引 i,其中 0 <= i < s.length 且 s[i] 是子音,那麼 t[i] = s[i]
|
||||
對於索引對 i, j,其中 0 <= i < j < s.length 且 s[i] 和 s[j] 都是母音,那麼 t[i] 的 ASCII 值不能高於 t[j]
|
||||
|
||||
母音定義: 'a', 'e', 'i', 'o', 'u' 以及它們的大寫形式
|
||||
|
||||
## 解題思路
|
||||
|
||||
### 初步分析
|
||||
- 這題主要考察什麼概念?
|
||||
這題主要考察字串處理和排序概念
|
||||
- 有什麼關鍵限制條件?
|
||||
- 預期時間/空間複雜度?
|
||||
O(n log k) / O(k),其中 n 為字串長度,k 為母音數量
|
||||
|
||||
### 解法概述
|
||||
1. **解法**:
|
||||
- 思路:
|
||||
1. 遍歷字串,收集所有母音及其位置
|
||||
2. 對母音字符進行排序
|
||||
3. 將排序後的母音按原位置重新放回字串
|
||||
- 時間複雜度:O(n + k log k) 其中 n 是字串長度,k 是母音數量
|
||||
- 空間複雜度:O(k) 存儲母音字符和位置
|
||||
|
||||
## 測試案例
|
||||
|
||||
### 範例輸入輸出
|
||||
```
|
||||
Input: s = "lEetcOde"
|
||||
Output: "lEOtcede"
|
||||
Explanation:
|
||||
母音 'E', 'e', 'O', 'e' 排序後變成 'E', 'O', 'e', 'e'
|
||||
```
|
||||
|
||||
### 邊界情況
|
||||
- `1 <= s.length <= 10^5`
|
||||
- `s` consists only of letters of the English alphabet in uppercase and lowercase.
|
||||
|
||||
## 學習筆記
|
||||
|
||||
### 今天學到什麼?
|
||||
-
|
||||
|
||||
### 遇到的困難
|
||||
-
|
||||
|
||||
### 改善方向
|
||||
-
|
||||
|
||||
### 相關題目
|
||||
- [題目編號] 題目名稱 - 相似概念
|
||||
- [題目編號] 題目名稱 - 進階版本
|
||||
|
||||
---
|
||||
**總結**: 這題的核心概念是...,適合練習...技巧。
|
108
problems/2785-sort-vowels-in-a-string/csharp/Program.cs
Normal file
108
problems/2785-sort-vowels-in-a-string/csharp/Program.cs
Normal file
@@ -0,0 +1,108 @@
|
||||
// LeetCode 2785: Sort Vowels In A String
|
||||
// 難度: Medium
|
||||
// 日期: 2025-09-11
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
public class Solution {
|
||||
public string SortVowels(string s) {
|
||||
// to char[]
|
||||
char[] sArray = s.ToCharArray();
|
||||
|
||||
// get all vowels
|
||||
string vowels = "aeiouAEIOU";
|
||||
List<int> vowelPositions = new List<int>();
|
||||
List<char> vowelChars = new List<char>();
|
||||
|
||||
for(int i = 0; i < sArray.Length; i++){
|
||||
if(vowels.Contains(sArray[i])){
|
||||
vowelPositions.Add(i);
|
||||
vowelChars.Add(sArray[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// sort all vowels
|
||||
vowelChars.Sort();
|
||||
|
||||
// insert vowels
|
||||
for(var i = 0; i < vowelPositions.Count; i++){
|
||||
sArray[vowelPositions[i]] = vowelChars[i];
|
||||
}
|
||||
|
||||
return new string(sArray);
|
||||
}
|
||||
}
|
||||
|
||||
// 測試程式
|
||||
public class Program {
|
||||
public static void Main() {
|
||||
Solution sol = new Solution();
|
||||
|
||||
// TODO: 加入測試案例
|
||||
TestCase1(sol);
|
||||
TestCase2(sol);
|
||||
TestCase3(sol);
|
||||
TestCase4(sol);
|
||||
TestCase5(sol);
|
||||
TestCase6(sol);
|
||||
TestCase7(sol);
|
||||
}
|
||||
|
||||
// 基本範例 - LeetCode官方例子
|
||||
static void TestCase1(Solution sol) {
|
||||
var s = "lEetcOde";
|
||||
var result = sol.SortVowels(s);
|
||||
var expected = "lEOtcede";
|
||||
Console.WriteLine($"Test 1: Input: \"{s}\", Result: \"{result}\", Expected: \"{expected}\", Pass: {result == expected}");
|
||||
}
|
||||
|
||||
// 只有子音 - 沒有母音的情況
|
||||
static void TestCase2(Solution sol) {
|
||||
var s = "lYmpH";
|
||||
var result = sol.SortVowels(s);
|
||||
var expected = "lYmpH";
|
||||
Console.WriteLine($"Test 2: Input: \"{s}\", Result: \"{result}\", Expected: \"{expected}\", Pass: {result == expected}");
|
||||
}
|
||||
|
||||
// 只有母音 - 測試排序功能
|
||||
static void TestCase3(Solution sol) {
|
||||
var s = "aEiOu";
|
||||
var result = sol.SortVowels(s);
|
||||
var expected = "EOaiu";
|
||||
Console.WriteLine($"Test 3: Input: \"{s}\", Result: \"{result}\", Expected: \"{expected}\", Pass: {result == expected}");
|
||||
}
|
||||
|
||||
// 混合大小寫母音
|
||||
static void TestCase4(Solution sol) {
|
||||
var s = "TestcasE";
|
||||
var result = sol.SortVowels(s);
|
||||
var expected = "TEstcase";
|
||||
Console.WriteLine($"Test 4: Input: \"{s}\", Result: \"{result}\", Expected: \"{expected}\", Pass: {result == expected}");
|
||||
}
|
||||
|
||||
// 單一字元 - 邊界情況
|
||||
static void TestCase5(Solution sol) {
|
||||
var s = "a";
|
||||
var result = sol.SortVowels(s);
|
||||
var expected = "a";
|
||||
Console.WriteLine($"Test 5: Input: \"{s}\", Result: \"{result}\", Expected: \"{expected}\", Pass: {result == expected}");
|
||||
}
|
||||
|
||||
// 重複母音
|
||||
static void TestCase6(Solution sol) {
|
||||
var s = "Aa";
|
||||
var result = sol.SortVowels(s);
|
||||
var expected = "Aa";
|
||||
Console.WriteLine($"Test 6: Input: \"{s}\", Result: \"{result}\", Expected: \"{expected}\", Pass: {result == expected}");
|
||||
}
|
||||
|
||||
// 較長的字串測試
|
||||
static void TestCase7(Solution sol) {
|
||||
var s = "RaInBoW";
|
||||
var result = sol.SortVowels(s);
|
||||
var expected = "RIanBoW";
|
||||
Console.WriteLine($"Test 7: Input: \"{s}\", Result: \"{result}\", Expected: \"{expected}\", Pass: {result == expected}");
|
||||
}
|
||||
}
|
0
legacy/2264 largestGoodInteger/C#/largestGoodInteger.csproj → problems/2785-sort-vowels-in-a-string/csharp/csharp.csproj
Executable file → Normal file
0
legacy/2264 largestGoodInteger/C#/largestGoodInteger.csproj → problems/2785-sort-vowels-in-a-string/csharp/csharp.csproj
Executable file → Normal file
@@ -0,0 +1,30 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.5.2.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "csharp", "csharp\csharp.csproj", "{CF022C7B-CAF3-706D-67E1-FB93518229B7}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestProject", "test\TestProject.csproj", "{C670389A-9CE7-B456-51E5-A79D56E199CF}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{CF022C7B-CAF3-706D-67E1-FB93518229B7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{CF022C7B-CAF3-706D-67E1-FB93518229B7}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{CF022C7B-CAF3-706D-67E1-FB93518229B7}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{CF022C7B-CAF3-706D-67E1-FB93518229B7}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{C670389A-9CE7-B456-51E5-A79D56E199CF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C670389A-9CE7-B456-51E5-A79D56E199CF}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C670389A-9CE7-B456-51E5-A79D56E199CF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C670389A-9CE7-B456-51E5-A79D56E199CF}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {50409315-93FE-4BEF-BAEC-4B70A05B634A}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
@@ -0,0 +1,91 @@
|
||||
# [3005] Count_elements_with_maximum_frequency
|
||||
|
||||
## 題目資訊
|
||||
- **難度**: Easy
|
||||
- **標籤**:
|
||||
- **題目連結**: https://leetcode.com/problems/count_elements_with_maximum_frequency/
|
||||
- **練習日期**: 2025-09-22
|
||||
- **目標複雜度**: 時間 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
|
||||
-
|
||||
|
||||
## 學習筆記
|
||||
- 今天學到:
|
||||
- 卡住與修正:
|
||||
- 待優化:
|
||||
|
||||
---
|
||||
**總結**:這題的核心在於 ______,適合練習 ______。
|
||||
|
@@ -0,0 +1,52 @@
|
||||
// LeetCode 3005: Count_elements_with_maximum_frequency
|
||||
// 難度: Easy
|
||||
// 日期: 2025-09-22
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
public class Solution {
|
||||
public int MaxFrequencyElements(int[] nums)
|
||||
{
|
||||
Dictionary<int, int> frequencyMap = new Dictionary<int, int>();
|
||||
|
||||
// put nums into dictionary map
|
||||
foreach (var num in nums)
|
||||
{
|
||||
if (!frequencyMap.ContainsKey(num))
|
||||
{
|
||||
frequencyMap.Add(num, 0);
|
||||
}
|
||||
frequencyMap[num]++;
|
||||
}
|
||||
|
||||
// find most frequency nums
|
||||
int maxFrequency = 0;
|
||||
if (frequencyMap.Count != 0)
|
||||
{
|
||||
maxFrequency = frequencyMap.Values.Max();
|
||||
}
|
||||
|
||||
// count if have same max frequency nus
|
||||
int count = 0;
|
||||
foreach (var dic in frequencyMap)
|
||||
{
|
||||
if (dic.Value == maxFrequency)
|
||||
{
|
||||
count += maxFrequency;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
}
|
||||
|
||||
public class Program {
|
||||
public static void Main() {
|
||||
var s = new Solution();
|
||||
// TODO: 可加入簡單輸入/輸出測試
|
||||
Console.WriteLine("Hello LeetCode 3005!");
|
||||
}
|
||||
}
|
||||
|
@@ -1,10 +1,9 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
|
@@ -0,0 +1,18 @@
|
||||
// LeetCode 3005: Count_elements_with_maximum_frequency
|
||||
// 難度: Easy
|
||||
// 日期: 2025-09-22
|
||||
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
// TODO: 根據題意調整簽名
|
||||
func solve(nums []int) int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func main() {
|
||||
fmt.Printf("Hello LeetCode 3005!\n")
|
||||
// TODO: 可加入簡單測試
|
||||
}
|
||||
|
@@ -0,0 +1,24 @@
|
||||
// LeetCode 3005 單元測試(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);
|
||||
}
|
||||
}
|
||||
|
@@ -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>
|
||||
|
@@ -0,0 +1,12 @@
|
||||
// LeetCode 3005 單元測試(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) }
|
||||
}
|
||||
|
@@ -0,0 +1,30 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.5.2.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "csharp", "csharp\csharp.csproj", "{CF022C7B-CAF3-706D-67E1-FB93518229B7}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestProject", "test\TestProject.csproj", "{C670389A-9CE7-B456-51E5-A79D56E199CF}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{CF022C7B-CAF3-706D-67E1-FB93518229B7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{CF022C7B-CAF3-706D-67E1-FB93518229B7}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{CF022C7B-CAF3-706D-67E1-FB93518229B7}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{CF022C7B-CAF3-706D-67E1-FB93518229B7}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{C670389A-9CE7-B456-51E5-A79D56E199CF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C670389A-9CE7-B456-51E5-A79D56E199CF}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C670389A-9CE7-B456-51E5-A79D56E199CF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C670389A-9CE7-B456-51E5-A79D56E199CF}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {15EA9854-706B-456C-B6A2-6AF4670868DE}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
82
problems/3227-vowels-game-in-a-string/README.md
Normal file
82
problems/3227-vowels-game-in-a-string/README.md
Normal file
@@ -0,0 +1,82 @@
|
||||
# [3227] Vowels Game In A String
|
||||
|
||||
## 題目資訊
|
||||
- **難度**: Medium
|
||||
- **標籤**: Math, String, Brainteaser, Game Theory
|
||||
- **題目連結**: https://leetcode.com/problems/vowels-game-in-a-string/
|
||||
- **練習日期**: 2025-09-12
|
||||
- **目標複雜度**: 時間 O(n)、空間 O(1)
|
||||
|
||||
## 題目描述
|
||||
Alice and Bob are playing a game on a string.
|
||||
|
||||
You are given a string `s`, Alice and Bob will take turns playing the following game where Alice starts **first**:
|
||||
|
||||
On Alice's turn, she has to remove any **non-empty** substring from `s` that contains an odd number of vowels.
|
||||
On Bob's turn, he has to remove any non-empty substring from `s` that contains an even number of vowels.
|
||||
The first player who cannot make a move on their turn loses the game. We assume that both Alice and Bob play optimally.
|
||||
|
||||
Return `true` if Alice wins the game, and `false` otherwise.
|
||||
|
||||
The English vowels are: `a`, `e`, `i`, `o`, and `u`.
|
||||
|
||||
## 先備條件與限制
|
||||
- 輸入限制:n ∈ [1, 10^5]、字符為小寫英文字母
|
||||
- 回傳/輸出格式:boolean 值,true 表示 Alice 獲勝
|
||||
|
||||
## 解題思路
|
||||
|
||||
### 初步分析
|
||||
- 類型:博弈論 / 數學 / 腦筋急轉彎
|
||||
- 關鍵觀察:
|
||||
- Alice 先手,需移除含奇數個母音的子字串
|
||||
- Bob 後手,需移除含偶數個母音的子字串
|
||||
- 複雜度目標理由:只需檢查是否存在母音
|
||||
|
||||
### 解法比較
|
||||
1. 解法A(基準/暴力):
|
||||
- 思路:
|
||||
發現 Alice 獲勝條件極其簡單
|
||||
- 正確性:
|
||||
只需檢查是否存在母音
|
||||
- 複雜度:O(n) / O(1)
|
||||
|
||||
### 常見陷阱
|
||||
- 邊界:空字串(題目保證 n≥1)、全母音、無母音
|
||||
- 過度複雜化:誤以為需要複雜的博弈分析
|
||||
- 計數錯誤:誤以為需要精確計算母音數量
|
||||
- 大小寫:題目保證小寫字母
|
||||
|
||||
## 測試案例
|
||||
|
||||
### 範例輸入輸出
|
||||
```
|
||||
Input: s = "leetcode"
|
||||
Output: true
|
||||
Explanation: Alice 可以移除 "leetcod"(含3個母音),剩下 "e",Bob 無法移除含偶數母音的子字串
|
||||
```
|
||||
|
||||
### 邊界清單
|
||||
- 全母音字串:Alice 立即移除整個字串獲勝
|
||||
- 無母音字串:Alice 無法行動敗北
|
||||
- 單一字符(母音/子音)
|
||||
- 混合字串(含有母音和子音)
|
||||
- 長字串壓力測試
|
||||
|
||||
## 複雜度分析
|
||||
- 最壞:時間 O(n)、空間 O(1)
|
||||
- 最佳:時間 O(1)(首字符即為母音)、空間 O(1)
|
||||
|
||||
## 相關題目 / Follow-up
|
||||
- LeetCode 345: Reverse Vowels of a String
|
||||
- LeetCode 1456: Maximum Number of Vowels in a Substring of Given Length
|
||||
- LeetCode 2062: Count Vowel Substrings of a String
|
||||
|
||||
## 學習筆記
|
||||
- 今天學到:
|
||||
- 卡住與修正:
|
||||
- 待優化:
|
||||
|
||||
---
|
||||
**總結**:這題的核心在於 ______,適合練習 ______。
|
||||
|
24
problems/3227-vowels-game-in-a-string/csharp/Program.cs
Normal file
24
problems/3227-vowels-game-in-a-string/csharp/Program.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
// LeetCode 3227: Vowels Game In A String
|
||||
// 難度: Medium
|
||||
// 日期: 2025-09-12
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
public class Solution {
|
||||
public bool DoesAliceWin(string s)
|
||||
{
|
||||
string vowels = "aeiou";
|
||||
|
||||
foreach (var character in s)
|
||||
{
|
||||
if (vowels.Contains(character))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
</Project>
|
4
problems/3227-vowels-game-in-a-string/go.mod
Normal file
4
problems/3227-vowels-game-in-a-string/go.mod
Normal file
@@ -0,0 +1,4 @@
|
||||
module leetcode/3227-vowels-game-in-a-string
|
||||
|
||||
go 1.18
|
||||
|
19
problems/3227-vowels-game-in-a-string/go/main.go
Normal file
19
problems/3227-vowels-game-in-a-string/go/main.go
Normal file
@@ -0,0 +1,19 @@
|
||||
// LeetCode 3227: Vowels Game In A String
|
||||
// 難度: Medium
|
||||
// 日期: 2025-09-12
|
||||
|
||||
package vowels
|
||||
|
||||
import "strings"
|
||||
|
||||
// DoesAliceWin returns true if the string contains any vowel.
|
||||
// Game theory reduces to: Alice wins iff there exists at least one vowel.
|
||||
func DoesAliceWin(s string) bool {
|
||||
const vowels = "aeiou"
|
||||
for _, ch := range s {
|
||||
if strings.ContainsRune(vowels, ch) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
168
problems/3227-vowels-game-in-a-string/test/SolutionTests.cs
Normal file
168
problems/3227-vowels-game-in-a-string/test/SolutionTests.cs
Normal file
@@ -0,0 +1,168 @@
|
||||
// LeetCode 3227: Vowels Game in a String 單元測試(xUnit)
|
||||
// Problem: Alice and Bob play a game. Alice removes substrings with odd vowels,
|
||||
// Bob removes substrings with even vowels. Alice wins if string has any vowels.
|
||||
|
||||
using Xunit;
|
||||
|
||||
public class SolutionTests
|
||||
{
|
||||
private readonly Solution _s = new Solution();
|
||||
|
||||
[Fact]
|
||||
public void Example1_StringWithVowels_AliceWins()
|
||||
{
|
||||
// Arrange
|
||||
var input = "leetcode"; // contains vowels: e,e,o,e
|
||||
var expected = true; // Alice wins
|
||||
|
||||
// Act
|
||||
var got = _s.DoesAliceWin(input);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expected, got);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Example2_StringWithoutVowels_BobWins()
|
||||
{
|
||||
// Arrange
|
||||
var input = "bcdf"; // no vowels
|
||||
var expected = false; // Bob wins (Alice can't make first move)
|
||||
|
||||
// Act
|
||||
var got = _s.DoesAliceWin(input);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expected, got);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AllVowels_AliceWins()
|
||||
{
|
||||
// Arrange
|
||||
var input = "aeiou"; // all vowels (odd count = 5)
|
||||
var expected = true; // Alice removes entire string
|
||||
|
||||
// Act
|
||||
var got = _s.DoesAliceWin(input);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expected, got);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SingleVowel_AliceWins()
|
||||
{
|
||||
// Arrange
|
||||
var input = "a"; // single vowel
|
||||
var expected = true; // Alice removes it immediately
|
||||
|
||||
// Act
|
||||
var got = _s.DoesAliceWin(input);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expected, got);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SingleConsonant_BobWins()
|
||||
{
|
||||
// Arrange
|
||||
var input = "b"; // single consonant, no vowels
|
||||
var expected = false; // Alice can't move
|
||||
|
||||
// Act
|
||||
var got = _s.DoesAliceWin(input);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expected, got);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MixedString_EvenVowelCount_AliceWins()
|
||||
{
|
||||
// Arrange
|
||||
var input = "programming"; // vowels: o,a,i (3 vowels, odd)
|
||||
var expected = true; // Alice can remove all vowels at once
|
||||
|
||||
// Act
|
||||
var got = _s.DoesAliceWin(input);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expected, got);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void LongStringNoVowels_BobWins()
|
||||
{
|
||||
// Arrange
|
||||
var input = "bcdfghjklmnpqrstvwxyz"; // all consonants
|
||||
var expected = false; // No vowels = Bob wins
|
||||
|
||||
// Act
|
||||
var got = _s.DoesAliceWin(input);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expected, got);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RepeatedVowels_AliceWins()
|
||||
{
|
||||
// Arrange
|
||||
var input = "aaaa"; // 4 vowels (even count)
|
||||
var expected = true; // Alice can remove 3, leaving 1 (Bob can't move)
|
||||
|
||||
// Act
|
||||
var got = _s.DoesAliceWin(input);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expected, got);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EdgeCases()
|
||||
{
|
||||
// Single character tests
|
||||
Assert.True(_s.DoesAliceWin("e")); // vowel
|
||||
Assert.False(_s.DoesAliceWin("x")); // consonant
|
||||
|
||||
// Two character tests
|
||||
Assert.True(_s.DoesAliceWin("ab")); // has vowel 'a'
|
||||
Assert.False(_s.DoesAliceWin("xy")); // no vowels
|
||||
|
||||
// Vowel at different positions
|
||||
Assert.True(_s.DoesAliceWin("xabc")); // vowel at start-middle
|
||||
Assert.True(_s.DoesAliceWin("abcx")); // vowel in middle
|
||||
Assert.True(_s.DoesAliceWin("xbca")); // vowel at end
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GameTheoryValidation()
|
||||
{
|
||||
// Test cases that validate the game theory logic:
|
||||
// If total vowels = 0: Alice loses (can't make first move)
|
||||
Assert.False(_s.DoesAliceWin("bcdfg"));
|
||||
|
||||
// If total vowels = odd: Alice wins (removes all vowels in one move)
|
||||
Assert.True(_s.DoesAliceWin("hello")); // e,o = 2 vowels (even), but Alice still wins
|
||||
Assert.True(_s.DoesAliceWin("beautiful")); // e,a,u,i,u = 5 vowels (odd)
|
||||
|
||||
// If total vowels = even > 0: Alice wins (leaves exactly 1 vowel for Bob)
|
||||
Assert.True(_s.DoesAliceWin("code")); // o,e = 2 vowels (even)
|
||||
Assert.True(_s.DoesAliceWin("education")); // e,u,a,i,o = 5 vowels, but any vowels = Alice wins
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("", false)] // empty string - no vowels
|
||||
[InlineData("aeiou", true)] // all vowels
|
||||
[InlineData("bcdfg", false)] // all consonants
|
||||
[InlineData("hello", true)] // mixed with vowels
|
||||
[InlineData("rhythm", false)] // no vowels (y not considered vowel)
|
||||
[InlineData("queue", true)] // multiple same vowels
|
||||
public void ParameterizedTests(string input, bool expected)
|
||||
{
|
||||
// Act & Assert
|
||||
Assert.Equal(expected, _s.DoesAliceWin(input));
|
||||
}
|
||||
}
|
@@ -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>
|
||||
|
20
problems/3227-vowels-game-in-a-string/test/edge_cases.md
Normal file
20
problems/3227-vowels-game-in-a-string/test/edge_cases.md
Normal file
@@ -0,0 +1,20 @@
|
||||
# 邊界情況清單(3227 Vowels Game In A String)
|
||||
|
||||
## 需要測試的邊界
|
||||
- [ ] 空輸入 / 單一元素
|
||||
- [ ] 重複元素 / 全相同
|
||||
- [ ] 極值(最小/最大)
|
||||
- [ ] 含負數 / 0 / 大數
|
||||
- [ ] 大資料量(接近上限)
|
||||
|
||||
## 額外案例
|
||||
### 案例 1
|
||||
- 輸入:
|
||||
- 預期:
|
||||
- 說明:
|
||||
|
||||
### 案例 2
|
||||
- 輸入:
|
||||
- 預期:
|
||||
- 說明:
|
||||
|
188
problems/3227-vowels-game-in-a-string/test/main_test.go
Normal file
188
problems/3227-vowels-game-in-a-string/test/main_test.go
Normal file
@@ -0,0 +1,188 @@
|
||||
// LeetCode 3227: Vowels Game in a String 單元測試(Go testing)
|
||||
// Problem: Alice and Bob play a game. Alice removes substrings with odd vowels,
|
||||
// Bob removes substrings with even vowels. Alice wins if string has any vowels.
|
||||
package vowels_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
vowels "leetcode/3227-vowels-game-in-a-string/go"
|
||||
)
|
||||
|
||||
func TestExample1(t *testing.T) {
|
||||
// "leetcode" contains vowels: e,e,o,e
|
||||
input := "leetcode"
|
||||
got := vowels.DoesAliceWin(input)
|
||||
want := true // Alice wins
|
||||
if got != want {
|
||||
t.Fatalf("input %q: want %v got %v", input, want, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestExample2(t *testing.T) {
|
||||
// "bcdf" has no vowels
|
||||
input := "bcdf"
|
||||
got := vowels.DoesAliceWin(input)
|
||||
want := false // Bob wins (Alice can't make first move)
|
||||
if got != want {
|
||||
t.Fatalf("input %q: want %v got %v", input, want, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAllVowels(t *testing.T) {
|
||||
// All vowels string - Alice removes entire string
|
||||
input := "aeiou"
|
||||
got := vowels.DoesAliceWin(input)
|
||||
want := true
|
||||
if got != want {
|
||||
t.Fatalf("input %q: want %v got %v", input, want, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSingleVowel(t *testing.T) {
|
||||
// Single vowel - Alice removes it immediately
|
||||
input := "a"
|
||||
got := vowels.DoesAliceWin(input)
|
||||
want := true
|
||||
if got != want {
|
||||
t.Fatalf("input %q: want %v got %v", input, want, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSingleConsonant(t *testing.T) {
|
||||
// Single consonant - Alice can't move
|
||||
input := "b"
|
||||
got := vowels.DoesAliceWin(input)
|
||||
want := false
|
||||
if got != want {
|
||||
t.Fatalf("input %q: want %v got %v", input, want, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMixedString(t *testing.T) {
|
||||
// "programming" has vowels: o,a,i
|
||||
input := "programming"
|
||||
got := vowels.DoesAliceWin(input)
|
||||
want := true // Alice can remove vowels
|
||||
if got != want {
|
||||
t.Fatalf("input %q: want %v got %v", input, want, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLongStringNoVowels(t *testing.T) {
|
||||
// All consonants - no vowels means Bob wins
|
||||
input := "bcdfghjklmnpqrstvwxyz"
|
||||
got := vowels.DoesAliceWin(input)
|
||||
want := false
|
||||
if got != want {
|
||||
t.Fatalf("input %q: want %v got %v", input, want, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRepeatedVowels(t *testing.T) {
|
||||
// Even number of same vowels - Alice can leave 1 for Bob
|
||||
input := "aaaa"
|
||||
got := vowels.DoesAliceWin(input)
|
||||
want := true
|
||||
if got != want {
|
||||
t.Fatalf("input %q: want %v got %v", input, want, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEdgeCases(t *testing.T) {
|
||||
testCases := []struct {
|
||||
input string
|
||||
want bool
|
||||
desc string
|
||||
}{
|
||||
{"e", true, "single vowel"},
|
||||
{"x", false, "single consonant"},
|
||||
{"ab", true, "has vowel 'a'"},
|
||||
{"xy", false, "no vowels"},
|
||||
{"xabc", true, "vowel in middle"},
|
||||
{"abcx", true, "vowel at start"},
|
||||
{"xbca", true, "vowel at end"},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := vowels.DoesAliceWin(tc.input)
|
||||
if got != tc.want {
|
||||
t.Fatalf("input %q (%s): want %v got %v", tc.input, tc.desc, tc.want, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGameTheoryValidation(t *testing.T) {
|
||||
testCases := []struct {
|
||||
input string
|
||||
want bool
|
||||
desc string
|
||||
}{
|
||||
// If total vowels = 0: Alice loses
|
||||
{"bcdfg", false, "no vowels - Alice can't move"},
|
||||
{"rhythm", false, "no vowels (y not counted)"},
|
||||
|
||||
// Any vowels > 0: Alice wins
|
||||
{"hello", true, "e,o vowels - Alice wins"},
|
||||
{"beautiful", true, "e,a,u,i,u vowels - Alice wins"},
|
||||
{"code", true, "o,e vowels - Alice wins"},
|
||||
{"education", true, "e,u,a,i,o vowels - Alice wins"},
|
||||
{"queue", true, "u,e,u,e vowels - Alice wins"},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := vowels.DoesAliceWin(tc.input)
|
||||
if got != tc.want {
|
||||
t.Fatalf("input %q (%s): want %v got %v", tc.input, tc.desc, tc.want, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestParameterized(t *testing.T) {
|
||||
testCases := []struct {
|
||||
input string
|
||||
want bool
|
||||
}{
|
||||
{"", false}, // empty string
|
||||
{"aeiou", true}, // all vowels
|
||||
{"bcdfg", false}, // all consonants
|
||||
{"hello", true}, // mixed with vowels
|
||||
{"rhythm", false}, // no vowels
|
||||
{"queue", true}, // multiple same vowels
|
||||
{"xyz", false}, // short no vowels
|
||||
{"programming", true}, // longer mixed
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.input, func(t *testing.T) {
|
||||
got := vowels.DoesAliceWin(tc.input)
|
||||
if got != tc.want {
|
||||
t.Errorf("doesAliceWin(%q) = %v, want %v", tc.input, got, tc.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Benchmark test
|
||||
func BenchmarkDoesAliceWin(b *testing.B) {
|
||||
testString := "abcdefghijklmnopqrstuvwxyz"
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
vowels.DoesAliceWin(testString)
|
||||
}
|
||||
}
|
||||
|
||||
// Example test for documentation
|
||||
func ExampleDoesAliceWin() {
|
||||
result1 := vowels.DoesAliceWin("leetcode")
|
||||
result2 := vowels.DoesAliceWin("bcdf")
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
// Output:
|
||||
// true
|
||||
// false
|
||||
}
|
99
templates/logs-template.md.tmpl
Normal file
99
templates/logs-template.md.tmpl
Normal 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/效能注意點/測試習慣
|
||||
- Go:slice/map/指標/錯誤處理/benchmark 習慣
|
||||
|
||||
## 🔄 困難案例復盤
|
||||
|
||||
### 案例1:題號/主題
|
||||
- 問題:
|
||||
- 嘗試:
|
||||
- 解決:
|
||||
- 學習:
|
||||
|
||||
### 案例2:題號/主題
|
||||
- 問題:
|
||||
- 嘗試:
|
||||
- 解決:
|
||||
- 學習:
|
||||
|
||||
## 📝 下月計畫
|
||||
- 目標題數:
|
||||
- 重點主題:
|
||||
- 練習節奏:
|
||||
- 要避免的坑:
|
||||
|
||||
## 💡 本月金句
|
||||
>
|
||||
|
||||
---
|
||||
**總結**:本月最大收穫是 ______,接下來專注 ______。
|
||||
|
@@ -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:
|
||||
```
|
||||
|
||||
### 邊界情況
|
||||
- [ ] 空陣列/空字串
|
||||
- [ ] 單一元素
|
||||
- [ ] 最大/最小值
|
||||
- [ ] 重複元素
|
||||
|
||||
## 學習筆記
|
||||
|
||||
### 今天學到什麼?
|
||||
-
|
||||
|
||||
### 遇到的困難
|
||||
-
|
||||
|
||||
### 改善方向
|
||||
-
|
||||
|
||||
### 相關題目
|
||||
- [題目編號] 題目名稱 - 相似概念
|
||||
- [題目編號] 題目名稱 - 進階版本
|
||||
|
||||
---
|
||||
**總結**: 這題的核心概念是...,適合練習...技巧。
|
105
templates/problem-template.md.tmpl
Normal file
105
templates/problem-template.md.tmpl
Normal 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:若輸入動態變化/資料流版本/線上查詢如何處理?
|
||||
|
||||
## 學習筆記
|
||||
- 今天學到:
|
||||
- 卡住點與修正:
|
||||
- 下次優化想法:
|
||||
|
||||
---
|
||||
**總結**:這題的核心在於 ______,適合練習 ______ 技巧。
|
||||
|
91
templates/problem/README.md.tmpl
Normal file
91
templates/problem/README.md.tmpl
Normal 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
|
||||
-
|
||||
|
||||
## 學習筆記
|
||||
- 今天學到:
|
||||
- 卡住與修正:
|
||||
- 待優化:
|
||||
|
||||
---
|
||||
**總結**:這題的核心在於 ______,適合練習 ______。
|
||||
|
24
templates/problem/csharp/Program.cs.tmpl
Normal file
24
templates/problem/csharp/Program.cs.tmpl
Normal 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}}!");
|
||||
}
|
||||
}
|
||||
|
5
legacy/3195 minimumArea/C#/MinimumArea.csproj → templates/problem/csharp/csharp.csproj.tmpl
Executable file → Normal file
5
legacy/3195 minimumArea/C#/MinimumArea.csproj → templates/problem/csharp/csharp.csproj.tmpl
Executable file → Normal file
@@ -1,10 +1,9 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
|
18
templates/problem/go/main.go.tmpl
Normal file
18
templates/problem/go/main.go.tmpl
Normal 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: 可加入簡單測試
|
||||
}
|
||||
|
24
templates/problem/test/SolutionTests.cs.tmpl
Normal file
24
templates/problem/test/SolutionTests.cs.tmpl
Normal 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);
|
||||
}
|
||||
}
|
||||
|
19
templates/problem/test/TestProject.csproj.tmpl
Normal file
19
templates/problem/test/TestProject.csproj.tmpl
Normal 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>
|
||||
|
20
templates/problem/test/edge_cases.md.tmpl
Normal file
20
templates/problem/test/edge_cases.md.tmpl
Normal file
@@ -0,0 +1,20 @@
|
||||
# 邊界情況清單({{NUMBER}} {{NAME_TITLE}})
|
||||
|
||||
## 需要測試的邊界
|
||||
- [ ] 空輸入 / 單一元素
|
||||
- [ ] 重複元素 / 全相同
|
||||
- [ ] 極值(最小/最大)
|
||||
- [ ] 含負數 / 0 / 大數
|
||||
- [ ] 大資料量(接近上限)
|
||||
|
||||
## 額外案例
|
||||
### 案例 1
|
||||
- 輸入:
|
||||
- 預期:
|
||||
- 說明:
|
||||
|
||||
### 案例 2
|
||||
- 輸入:
|
||||
- 預期:
|
||||
- 說明:
|
||||
|
12
templates/problem/test/main_test.go.tmpl
Normal file
12
templates/problem/test/main_test.go.tmpl
Normal 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) }
|
||||
}
|
||||
|
188
utils/leetcode_helper.sh
Executable file
188
utils/leetcode_helper.sh
Executable file
@@ -0,0 +1,188 @@
|
||||
# 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 Case(two-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"
|
||||
}
|
||||
|
||||
# 顯示說明
|
||||
show_help() {
|
||||
cat << EOF
|
||||
LeetCode Practice Helper
|
||||
|
||||
用法:
|
||||
$0 problem <題號> <題目名稱-kebab> <難度>
|
||||
$0 log [YYYY-MM]
|
||||
$0 readme
|
||||
$0 -h | --help
|
||||
|
||||
說明:
|
||||
problem 建立新題目(會建立 C#/Go 骨架、測試模板與 README)
|
||||
log 建立月度學習日誌(預設為本月,或指定 YYYY-MM)
|
||||
readme 顯示題目數量統計(可擴充為寫回 README)
|
||||
|
||||
範例:
|
||||
$0 problem 1 two-sum Easy
|
||||
$0 problem 3025 find-the-number-of-ways-to-place-people-i Medium
|
||||
$0 log 2025-09
|
||||
$0 readme
|
||||
|
||||
測試:
|
||||
建議使用 utils/run_tests.sh 執行,例:
|
||||
utils/run_tests.sh 3025 [all|csharp|go]
|
||||
EOF
|
||||
}
|
||||
|
||||
# 建立測試檔案(來自 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"
|
||||
|
||||
# 不再產生每題的 run_tests.sh,請改用 utils/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 "測試: utils/run_tests.sh ${number_pad}-${name_slug} [all|csharp|go]"
|
||||
}
|
||||
|
||||
# 更新主 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"
|
||||
}
|
||||
|
||||
# 入口
|
||||
|
||||
# --help
|
||||
if [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then
|
||||
show_help
|
||||
exit 0
|
||||
fi
|
||||
|
||||
case "${1:-}" in
|
||||
problem)
|
||||
create_problem "${2:-}" "${3:-}" "${4:-}" ;;
|
||||
readme)
|
||||
update_readme ;;
|
||||
log)
|
||||
create_monthly_log "${2:-}" ;;
|
||||
*)
|
||||
show_help
|
||||
;;
|
||||
esac
|
125
utils/run_tests.sh
Executable file
125
utils/run_tests.sh
Executable file
@@ -0,0 +1,125 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
# Usage:
|
||||
# utils/run_tests.sh <problem> [all|csharp|go]
|
||||
# Examples:
|
||||
# utils/run_tests.sh 3025
|
||||
# utils/run_tests.sh 3025 csharp
|
||||
# utils/run_tests.sh problems/3025-find-the-number-of-ways-to-place-people-i go
|
||||
# utils/run_tests.sh 3516-find-closest-person all
|
||||
# Help:
|
||||
# utils/run_tests.sh -h | --help
|
||||
# List:
|
||||
# utils/run_tests.sh --list
|
||||
|
||||
SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
||||
ROOT_DIR=$(cd "$SCRIPT_DIR/.." && pwd)
|
||||
|
||||
show_help() {
|
||||
cat << EOF
|
||||
Run tests for a problem folder.
|
||||
|
||||
Usage:
|
||||
$0 <problem> [all|csharp|go]
|
||||
$0 --list
|
||||
|
||||
Where <problem> can be:
|
||||
- A number (e.g., 3025)
|
||||
- A 4-digit + slug folder name (e.g., 3025-find-the-number-of-ways-to-place-people-i)
|
||||
- A relative path under problems/ (e.g., problems/3025-find-the-number-of-ways-to-place-people-i)
|
||||
|
||||
Examples:
|
||||
$0 3025 # run both C# and Go tests
|
||||
$0 3025 csharp # only C#
|
||||
$0 3516 go # only Go
|
||||
$0 3516-find-closest-person all
|
||||
$0 problems/3516-find-closest-person all
|
||||
$0 --list # list available problems
|
||||
EOF
|
||||
}
|
||||
|
||||
if [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then
|
||||
show_help
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ "${1:-}" == "--list" ]]; then
|
||||
echo "Available problems (from problems/):"
|
||||
# List directories matching 4-digit prefix
|
||||
find "$ROOT_DIR/problems" -maxdepth 1 -mindepth 1 -type d -printf "%f\n" \
|
||||
| sort \
|
||||
| awk 'BEGIN{printf("%-8s %s\n","Number","Slug"); printf("%-8s %s\n","------","----");}
|
||||
{num=substr($0,1,4); slug=substr($0,6); printf("%-8s %s\n", num, $0)}'
|
||||
exit 0
|
||||
fi
|
||||
|
||||
problem_arg="${1:-}"
|
||||
lang="${2:-all}"
|
||||
|
||||
if [[ -z "$problem_arg" ]]; then
|
||||
show_help >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
resolve_problem_dir() {
|
||||
local arg="$1"
|
||||
if [[ -d "$ROOT_DIR/$arg" ]]; then
|
||||
echo "$ROOT_DIR/$arg"
|
||||
return 0
|
||||
fi
|
||||
if [[ "$arg" =~ ^[0-9]+$ ]]; then
|
||||
local num=$(printf "%04d" "$arg")
|
||||
local match
|
||||
match=$(find "$ROOT_DIR/problems" -maxdepth 1 -type d -name "${num}-*" | head -n 1 || true)
|
||||
if [[ -n "$match" ]]; then
|
||||
echo "$match"; return 0
|
||||
fi
|
||||
fi
|
||||
# try exact name under problems
|
||||
if [[ -d "$ROOT_DIR/problems/$arg" ]]; then
|
||||
echo "$ROOT_DIR/problems/$arg"; return 0
|
||||
fi
|
||||
echo "Cannot resolve problem directory from '$arg'" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
PROB_DIR=$(resolve_problem_dir "$problem_arg")
|
||||
TEST_DIR="$PROB_DIR/test"
|
||||
CS_DIR="$PROB_DIR/csharp"
|
||||
GO_DIR="$PROB_DIR/go"
|
||||
|
||||
run_csharp() {
|
||||
if [[ ! -d "$CS_DIR" || ! -d "$TEST_DIR" ]]; then
|
||||
echo "[C#] Skipped (missing csharp or test folder)"; return 0
|
||||
fi
|
||||
echo "📋 C# 測試結果:"
|
||||
if (cd "$CS_DIR" && dotnet build >/dev/null 2>&1); then
|
||||
(cd "$TEST_DIR" && dotnet test --logger "console;verbosity=minimal") || { echo "❌ C# 測試失敗"; return 1; }
|
||||
echo "✅ C# 測試通過"
|
||||
else
|
||||
echo "❌ C# 編譯失敗"; return 1
|
||||
fi
|
||||
}
|
||||
|
||||
run_go() {
|
||||
if [[ ! -d "$GO_DIR" || ! -d "$TEST_DIR" ]]; then
|
||||
echo "[Go] Skipped (missing go or test folder)"; return 0
|
||||
fi
|
||||
echo "📋 Go 測試結果:"
|
||||
if (cd "$GO_DIR" && go build >/dev/null 2>&1); then
|
||||
(cd "$TEST_DIR" && go test -v) || { echo "❌ Go 測試失敗"; return 1; }
|
||||
echo "✅ Go 測試通過"
|
||||
else
|
||||
echo "❌ Go 編譯失敗"; return 1
|
||||
fi
|
||||
}
|
||||
|
||||
case "$lang" in
|
||||
all) run_csharp; run_go ;;
|
||||
csharp) run_csharp ;;
|
||||
go) run_go ;;
|
||||
*) echo "Unknown lang '$lang' (use all|csharp|go)" >&2; exit 1 ;;
|
||||
esac
|
||||
|
||||
echo "📊 測試完成: $PROB_DIR"
|
Reference in New Issue
Block a user