Compare commits
3 Commits
38f948f691
...
0c278fa275
Author | SHA1 | Date | |
---|---|---|---|
0c278fa275 | |||
c760afc0f7 | |||
b99708dc36 |
@@ -5,7 +5,8 @@
|
||||
### Week 1
|
||||
| 日期 | 題目 | 難度 | 語言 | 耗時 | 狀態 | 心得 |
|
||||
|------|------|------|------|------|------|------|
|
||||
| 09-01 | Maximum Average Pass Ratio | Medium | C# | 1hr | Done | 第一次用到Priority Queue |
|
||||
| 09/01 | Maximum Average Pass Ratio | Medium | C# | 1hr | Done | 第一次用到Priority Queue |
|
||||
| 09/02| Find The Number of Ways to Place People I | Medium | C# | 0.5hr | Done | 二維點位判斷 |
|
||||
|
||||
### Week 2
|
||||
| 日期 | 題目 | 難度 | 語言 | 耗時 | 狀態 | 心得 |
|
||||
@@ -25,13 +26,13 @@
|
||||
## 📈 本月統計
|
||||
|
||||
### 完成情況
|
||||
- **總練習天數**: 1 天
|
||||
- **完成題數**: 1題
|
||||
- **語言分布**: C# 1(題), Go 0(題)
|
||||
- **難度分布**: Easy 0(題), Medium 1(題), Hard 0(題)
|
||||
- **總練習天數**: 2 天
|
||||
- **完成題數**: 2題
|
||||
- **語言分布**: C# 2(題), Go 0(題)
|
||||
- **難度分布**: Easy 0(題), Medium 2(題), Hard 0(題)
|
||||
|
||||
### 時間投入
|
||||
- **總時間**: 1小時
|
||||
- **總時間**: 1.5小時
|
||||
- **平均每題**: 分鐘
|
||||
- **每日平均**: 分鐘
|
||||
|
||||
|
@@ -0,0 +1,3 @@
|
||||
module leetcode-3025
|
||||
|
||||
go 1.18
|
@@ -0,0 +1,70 @@
|
||||
// LeetCode 3025: Find The Number Of Ways To Place People I
|
||||
// 難度: Medium
|
||||
// 日期: 2025-09-02
|
||||
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
// TODO: 實作解法
|
||||
func numberOfPairs(points [][]int) int {
|
||||
n := len(points)
|
||||
count := 0;
|
||||
|
||||
for i:= 0; i < n; i++{
|
||||
for j := 0; j < n; j++{
|
||||
if i == j {
|
||||
continue
|
||||
}
|
||||
|
||||
pointA := points[i]
|
||||
pointB := points[j]
|
||||
|
||||
if pointA[0] <= pointB[0] && pointA[1] >= pointB[1] {
|
||||
hasOtherPoint := false;
|
||||
minX := pointA[0]
|
||||
maxX := pointB[0]
|
||||
minY := pointB[1]
|
||||
maxY := pointA[1]
|
||||
|
||||
for k := 0; k < n; k++{
|
||||
if i == k || j == k{
|
||||
continue
|
||||
}
|
||||
|
||||
pointC := points[k]
|
||||
|
||||
if minX <= pointC[0] && pointC[0] <= maxX && minY <= pointC[1] && pointC[1] <= maxY{
|
||||
hasOtherPoint = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !hasOtherPoint{
|
||||
count++
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
func main() {
|
||||
testCase()
|
||||
}
|
||||
|
||||
// 測試案例模板
|
||||
func testCase() {
|
||||
// Input:
|
||||
points := [][]int{
|
||||
{6, 2},
|
||||
{4, 4},
|
||||
{2, 6},
|
||||
}
|
||||
// Expected:
|
||||
fmt.Printf("Test Case: [[6,2],[4,4],[2,6]]\n")
|
||||
fmt.Printf("Expected: 2\n")
|
||||
// Actual:
|
||||
result := numberOfPairs(points)
|
||||
fmt.Printf("Result: %d\n", result)
|
||||
}
|
@@ -0,0 +1,239 @@
|
||||
// LeetCode 3025 Go 單元測試
|
||||
package main
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"testing"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func TestCase1_ExampleFromProblem(t *testing.T) {
|
||||
// Arrange
|
||||
points := [][]int{
|
||||
{6, 2},
|
||||
{4, 4},
|
||||
{2, 6},
|
||||
}
|
||||
expected := 2
|
||||
|
||||
// Act
|
||||
result := numberOfPairs(points)
|
||||
|
||||
// Assert
|
||||
if result != expected {
|
||||
t.Errorf("TestCase1 failed. Expected: %v, Got: %v", expected, result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCase2_TwoPoints(t *testing.T) {
|
||||
// Arrange
|
||||
points := [][]int{
|
||||
{1, 3},
|
||||
{2, 1},
|
||||
}
|
||||
expected := 1
|
||||
|
||||
// Act
|
||||
result := numberOfPairs(points)
|
||||
|
||||
// Assert
|
||||
if result != expected {
|
||||
t.Errorf("TestCase2 failed. Expected: %v, Got: %v", expected, result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCase3_NoValidPairs(t *testing.T) {
|
||||
// Arrange - 沒有有效點對的情況
|
||||
points := [][]int{
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{3, 3},
|
||||
}
|
||||
expected := 0
|
||||
|
||||
// Act
|
||||
result := numberOfPairs(points)
|
||||
|
||||
// Assert
|
||||
if result != expected {
|
||||
t.Errorf("TestCase3 failed. Expected: %v, Got: %v", expected, result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCase4_SameXCoordinate(t *testing.T) {
|
||||
// Arrange - x 座標相同的情況
|
||||
points := [][]int{
|
||||
{3, 5}, // A
|
||||
{3, 2}, // B
|
||||
{3, 1}, // C
|
||||
}
|
||||
// 詳細分析:
|
||||
// (A, B): (3,5) -> (3,2) ✓ 矩形是線段,無其他點
|
||||
// (A, C): (3,5) -> (3,1) ✗ 點B在矩形內
|
||||
// (B, C): (3,2) -> (3,1) ✓ 矩形是線段,無其他點
|
||||
expected := 2
|
||||
|
||||
// Act
|
||||
result := numberOfPairs(points)
|
||||
|
||||
// Assert
|
||||
if result != expected {
|
||||
t.Errorf("TestCase4 failed. Expected: %v, Got: %v", expected, result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCase5_SameYCoordinate(t *testing.T) {
|
||||
// Arrange - y 座標相同的情況
|
||||
points := [][]int{
|
||||
{1, 4}, // A
|
||||
{3, 4}, // B
|
||||
{5, 4}, // C
|
||||
}
|
||||
// 詳細分析:
|
||||
// (A, B): (1,4) -> (3,4) ✓ 矩形是線段,無其他點
|
||||
// (A, C): (1,4) -> (5,4) ✗ 點B在矩形內
|
||||
// (B, C): (3,4) -> (5,4) ✓ 矩形是線段,無其他點
|
||||
expected := 2
|
||||
|
||||
// Act
|
||||
result := numberOfPairs(points)
|
||||
|
||||
// Assert
|
||||
if result != expected {
|
||||
t.Errorf("TestCase5 failed. Expected: %v, Got: %v", expected, result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCase6_PointsInsideRectangle(t *testing.T) {
|
||||
// Arrange - 矩形內有其他點的情況
|
||||
points := [][]int{
|
||||
{0, 4}, // A
|
||||
{4, 0}, // B
|
||||
{2, 2}, // C
|
||||
}
|
||||
// 詳細分析:
|
||||
// (A, B): (0,4) -> (4,0) ✗ 點C在矩形內
|
||||
// (A, C): (0,4) -> (2,2) ✓ 點B不在矩形內
|
||||
// (C, B): (2,2) -> (4,0) ✓ 點A不在矩形內
|
||||
expected := 2
|
||||
|
||||
// Act
|
||||
result := numberOfPairs(points)
|
||||
|
||||
// Assert
|
||||
if result != expected {
|
||||
t.Errorf("TestCase6 failed. Expected: %v, Got: %v", expected, result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCase7_PointsOnBorder(t *testing.T) {
|
||||
// Arrange - 點在矩形邊界上的情況
|
||||
points := [][]int{
|
||||
{0, 3}, // A
|
||||
{3, 0}, // B
|
||||
{0, 0}, // C
|
||||
}
|
||||
// 詳細分析:
|
||||
// (A, B): (0,3) -> (3,0) ✗ 點C在矩形邊界上
|
||||
// (A, C): (0,3) -> (0,0) ✓ 矩形是線段,點B不在其中
|
||||
// (C, B): (0,0) -> (3,0) ✓ 矩形是線段,點A不在其中
|
||||
expected := 2
|
||||
|
||||
// Act
|
||||
result := numberOfPairs(points)
|
||||
|
||||
// Assert
|
||||
if result != expected {
|
||||
t.Errorf("TestCase7 failed. Expected: %v, Got: %v", expected, result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEdgeCases_MinimumPoints(t *testing.T) {
|
||||
// Arrange - 最少點數情況 (題目限制 n >= 2)
|
||||
points := [][]int{
|
||||
{0, 1},
|
||||
{1, 0},
|
||||
}
|
||||
expected := 1 // (0,1) 在 (1,0) 的左上方
|
||||
|
||||
// Act
|
||||
result := numberOfPairs(points)
|
||||
|
||||
// Assert
|
||||
if result != expected {
|
||||
t.Errorf("TestEdgeCases_MinimumPoints failed. Expected: %v, Got: %v", expected, result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEdgeCases_MaxCoordinateValues(t *testing.T) {
|
||||
// Arrange - 最大座標值情況 (題目限制 0 <= coordinates <= 50)
|
||||
points := [][]int{
|
||||
{0, 50}, // A
|
||||
{50, 0}, // B
|
||||
{25, 25}, // C
|
||||
}
|
||||
expected := 2 // (A,C) 和 (C,B) 有效
|
||||
|
||||
// Act
|
||||
result := numberOfPairs(points)
|
||||
|
||||
// Assert
|
||||
if result != expected {
|
||||
t.Errorf("TestEdgeCases_MaxCoordinateValues failed. Expected: %v, Got: %v", expected, result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEdgeCases_EmptyArray(t *testing.T) {
|
||||
// Arrange - 空陣列情況
|
||||
points := [][]int{}
|
||||
expected := 0
|
||||
|
||||
// Act
|
||||
result := numberOfPairs(points)
|
||||
|
||||
// Assert
|
||||
if result != expected {
|
||||
t.Errorf("TestEdgeCases_EmptyArray failed. Expected: %v, Got: %v", expected, result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEdgeCases_MaxPoints_RandomPattern(t *testing.T) {
|
||||
// Arrange - 50個不同的點,隨機模式
|
||||
points := make([][]int, 0, 50)
|
||||
usedPoints := make(map[string]bool)
|
||||
|
||||
// 使用固定種子確保測試可重現
|
||||
rand.Seed(42)
|
||||
|
||||
for len(points) < 50 {
|
||||
x := rand.Intn(51) // 0-50
|
||||
y := rand.Intn(51) // 0-50
|
||||
pointKey := fmt.Sprintf("%d,%d", x, y)
|
||||
|
||||
if !usedPoints[pointKey] {
|
||||
usedPoints[pointKey] = true
|
||||
points = append(points, []int{x, y})
|
||||
}
|
||||
}
|
||||
|
||||
// Act
|
||||
result := numberOfPairs(points)
|
||||
|
||||
// Assert
|
||||
if result < 0 {
|
||||
t.Errorf("TestEdgeCases_MaxPoints_RandomPattern failed. Result should be non-negative, got: %v", result)
|
||||
}
|
||||
if result > 50*49 {
|
||||
t.Errorf("TestEdgeCases_MaxPoints_RandomPattern failed. Result should not exceed 50*49, got: %v", result)
|
||||
}
|
||||
|
||||
// 額外驗證:確保所有點都是不同的
|
||||
distinctPoints := make(map[string]bool)
|
||||
for _, point := range points {
|
||||
key := fmt.Sprintf("%d,%d", point[0], point[1])
|
||||
distinctPoints[key] = true
|
||||
}
|
||||
if len(distinctPoints) != 50 {
|
||||
t.Errorf("TestEdgeCases_MaxPoints_RandomPattern failed. Expected 50 distinct points, got: %v", len(distinctPoints))
|
||||
}
|
||||
}
|
39
problems/3025-find-the-number-of-ways-to-place-people-i/test/run_tests.sh
Executable file
39
problems/3025-find-the-number-of-ways-to-place-people-i/test/run_tests.sh
Executable file
@@ -0,0 +1,39 @@
|
||||
#!/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 "📊 測試完成!"
|
Reference in New Issue
Block a user