Skip to content

Commit 18d995c

Browse files
committed
Add: Add 2025/1/21
1 parent 7ac8480 commit 18d995c

File tree

2 files changed

+128
-0
lines changed

2 files changed

+128
-0
lines changed

2017-Grid Game/Note.md

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
# 2017. Grid Game
2+
3+
You are given a 0-indexed 2D array `grid` of size `2 x n`,
4+
where `grid[r][c]` represents the number of points at position `(r, c)` on the matrix.
5+
Two robots are playing a game on this matrix.
6+
7+
Both robots initially start at `(0, 0)` and want to reach `(1, n-1)`.
8+
Each robot may only move to the right `((r, c)` to `(r, c + 1))` or
9+
down `((r, c)` to `(r + 1, c))`.
10+
11+
At the start of the game, the first robot moves from `(0, 0)` to `(1, n-1)`,
12+
collecting all the points from the cells on its path.
13+
For all cells `(r, c)` traversed on the path, `grid[r][c]` is set to 0.
14+
Then, the second robot moves from `(0, 0)` to `(1, n-1)`,
15+
collecting the points on its path.
16+
Note that their paths may intersect with one another.
17+
18+
The first robot wants to minimize the number of points collected by the second robot.
19+
In contrast, the second robot wants to maximize the number of points it collects.
20+
If both robots play optimally, return the number of points collected by the second robot.
21+
22+
## 基礎思路
23+
24+
我們可以將問題轉換為分析 `grid` 的兩個獨立一維陣列:`grid[0]``grid[1]`
25+
考慮 **第一機器人**的行動邏輯:
26+
27+
1. **第一機器人轉移點**
28+
當第一機器人在第 `index` 位置從 `grid[0]` 切換到 `grid[1]` 時:
29+
- `grid[0]`:第 `index` 位置之前(包含 `index`)的所有分數會被清空。
30+
- `grid[1]`:第 `index` 位置之後(包含 `index`)的所有分數會被清空。
31+
32+
2. **剩餘的有效分數**
33+
經過上述清空後:
34+
- `grid[0]` 有效分數範圍為第 `index + 1` 之後的部分。
35+
- `grid[1]` 有效分數範圍為第 `index - 1` 之前的部分。
36+
37+
**機器人二**的目標是最大化分數,根據剩餘分數,其得分可能來自以下兩種情況:
38+
1. **選擇剩餘的 `grid[0]` 分數**:吃完 `grid[0]` 的所有分數。
39+
2. **選擇剩餘的 `grid[1]` 分數**:吃完 `grid[1]` 的所有分數。
40+
41+
由於機器人二會選擇最大化得分的路徑,因此其最終得分為上述兩者中的較大值。
42+
43+
我們的目標是檢索所有可能的 `index`,對每個 `index` 計算機器人二的得分,並在所有情況中選擇 **最小化機器人二得分** 的情況。最小值即為答案。
44+
45+
> 小技巧:
46+
> - 一個節省空間的方法是先紀錄 topSum 是整個 `grid[0]` 加總。並先把 bottomSum 的設為 `0`
47+
> - 當是 index 時,此時的上方的分數是 topSum 減去 `grid[0][index]`,下方的分數是 bottomSum 加上 `grid[1][index]`
48+
> - 這樣能大幅減少計算量與所需暫存空間。
49+
50+
## 解題步驟
51+
52+
### Step 1: 紀錄 N 長度
53+
54+
```typescript
55+
const n = grid[0].length;
56+
```
57+
58+
### Step 2: 初始化 `topSum` 以及 `bottomSum`
59+
60+
```typescript
61+
let topSum = grid[0].reduce((a, b) => a + b, 0); // 紀錄 topSum 是整個 `grid[0]` 加總
62+
let bottomSum = 0; // 初始化 bottomSum為 `0`
63+
```
64+
65+
### Step 3: 計算每個 `index` 的得分並記錄最小值
66+
67+
```typescript
68+
// 初始化最小值
69+
let minSecondRobotScore = Infinity;
70+
71+
// 模擬每個 index 的情況
72+
for (let i = 0; i < n; i++) {
73+
// 先減去 當前 index 在 grid[0] 的分數
74+
// 因為對於 topSum 來說,需要的是 index 之後的累積分數
75+
topSum -= grid[0][i];
76+
77+
// 計算第二機器人再該 index 分割下的能獲取的最大分數
78+
const secondRobotScore = Math.max(topSum, bottomSum);
79+
80+
// 更新第二機器人可能獲取的最小分數
81+
minSecondRobotScore = Math.min(minSecondRobotScore, secondRobotScore);
82+
83+
// 移動到下一個 index 須把當前 index 的分數加入 bottomSum
84+
// 因為 bottomSum 是從計算 index 之前的累積分數
85+
bottomSum += grid[1][i];
86+
}
87+
```
88+
89+
## 時間複雜度
90+
- 計算加總需要 $O(n)$ 時間
91+
- 計算每個 index 的得分需要 $O(n)$ 時間
92+
- 因此總時間複雜度為 $O(n)$。
93+
94+
> $O(n)$
95+
96+
## 空間複雜度
97+
- 我們只使用了常數額外空間,因此空間複雜度為 $O(1)$。
98+
- 這是一個非常高效的解決方案。
99+
100+
> $O(1)$

2017-Grid Game/answer.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
function gridGame(grid: number[][]): number {
2+
// Get the number of columns (Grid is 2xN)
3+
const n = grid[0].length;
4+
5+
// Init the top and bottom score
6+
let topSum = grid[0].reduce((a, b) => a + b, 0);
7+
let bottomSum = 0;
8+
9+
// Init the second robot score
10+
let minSecondRobotScore = Infinity;
11+
12+
// Simulation for the first robot
13+
for (let i = 0; i < n; i++) {
14+
// Update top score
15+
topSum -= grid[0][i];
16+
17+
// Calculate the second robot score
18+
const secondRobotScore = Math.max(topSum, bottomSum);
19+
20+
// Update the minimum second robot score
21+
minSecondRobotScore = Math.min(minSecondRobotScore, secondRobotScore);
22+
23+
// Update bottom score
24+
bottomSum += grid[1][i];
25+
}
26+
27+
return minSecondRobotScore;
28+
}

0 commit comments

Comments
 (0)