Skip to content

Commit fdf40b4

Browse files
authored
feat: update solutions to lc problem: No.2304 (doocs#1991)
No.2304.Minimum Path Cost in a Grid
1 parent 6821a29 commit fdf40b4

File tree

4 files changed

+78
-86
lines changed

4 files changed

+78
-86
lines changed

solution/2300-2399/2304.Minimum Path Cost in a Grid/README.md

+22-30
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,9 @@ $$
6767

6868
其中 $\text{moveCost}[grid[i - 1][k]][j]$ 表示从第 $i - 1$ 行第 $k$ 列移动到第 $i$ 行第 $j$ 列的代价。
6969

70-
最终答案即为 $f[m - 1][j]$ 的最小值,其中 $j$ 的取值范围为 $[0, n - 1]$。
70+
最终答案即为 $\min_{0 \leq j < n} \{f[m - 1][j]\}$。
7171

72-
由于每次转移只需要用到上一行的状态,因此可以将空间复杂度优化到 $O(n)$。
72+
由于每次转移只需要用到上一行的状态,因此我们可以使用滚动数组的方式,将空间复杂度优化到 $O(n)$。
7373

7474
时间复杂度 $O(m \times n^2)$,空间复杂度 $O(n)$。其中 $m$ 和 $n$ 分别为网格的行数和列数。
7575

@@ -172,25 +172,21 @@ func minPathCost(grid [][]int, moveCost [][]int) int {
172172
```rust
173173
impl Solution {
174174
pub fn min_path_cost(grid: Vec<Vec<i32>>, move_cost: Vec<Vec<i32>>) -> i32 {
175-
let (m, n) = (grid.len(), grid[0].len());
176-
let mut dp = vec![0; n];
177-
for i in 0..m - 1 {
178-
let mut counter = vec![i32::MAX; n];
175+
let m = grid.len();
176+
let n = grid[0].len();
177+
let mut f = grid[0].clone();
178+
179+
for i in 1..m {
180+
let mut g: Vec<i32> = vec![i32::MAX; n];
179181
for j in 0..n {
180-
let val = grid[i][j];
181182
for k in 0..n {
182-
counter[k] = counter[k].min(val + move_cost[val as usize][k] + dp[j]);
183+
g[j] = g[j].min(f[k] + move_cost[grid[i - 1][k] as usize][j] + grid[i][j]);
183184
}
184185
}
185-
for j in 0..n {
186-
dp[j] = counter[j];
187-
}
186+
f.copy_from_slice(&g);
188187
}
189-
let mut res = i32::MAX;
190-
for i in 0..n {
191-
res = res.min(dp[i] + grid[m - 1][i]);
192-
}
193-
res
188+
189+
f.iter().cloned().min().unwrap_or(0)
194190
}
195191
}
196192
```
@@ -199,23 +195,19 @@ impl Solution {
199195

200196
```ts
201197
function minPathCost(grid: number[][], moveCost: number[][]): number {
202-
const m = grid.length,
203-
n = grid[0].length;
204-
let pre = grid[0].slice();
205-
for (let i = 1; i < m; i++) {
206-
let next = new Array(n);
207-
for (let j = 0; j < n; j++) {
208-
const key = grid[i - 1][j];
209-
for (let k = 0; k < n; k++) {
210-
let sum = pre[j] + moveCost[key][k] + grid[i][k];
211-
if (j == 0 || next[k] > sum) {
212-
next[k] = sum;
213-
}
198+
const m = grid.length;
199+
const n = grid[0].length;
200+
const f = grid[0];
201+
for (let i = 1; i < m; ++i) {
202+
const g: number[] = Array(n).fill(Infinity);
203+
for (let j = 0; j < n; ++j) {
204+
for (let k = 0; k < n; ++k) {
205+
g[j] = Math.min(g[j], f[k] + moveCost[grid[i - 1][k]][j] + grid[i][j]);
214206
}
215207
}
216-
pre = next;
208+
f.splice(0, n, ...g);
217209
}
218-
return Math.min(...pre);
210+
return Math.min(...f);
219211
}
220212
```
221213

solution/2300-2399/2304.Minimum Path Cost in a Grid/README_EN.md

+36-28
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,22 @@ So the total cost of this path is 5 + 1 = 6.
4949

5050
## Solutions
5151

52+
**Solution 1: Dynamic Programming**
53+
54+
We define $f[i][j]$ to represent the minimum path cost from the first row to the $i$th row and $j$th column. Since we can only move from a column in the previous row to a column in the current row, the value of $f[i][j]$ can be transferred from $f[i - 1][k]$, where the range of $k$ is $[0, n - 1]$. Therefore, the state transition equation is:
55+
56+
$$
57+
f[i][j] = \min_{0 \leq k < n} \{f[i - 1][k] + \text{moveCost}[grid[i - 1][k]][j] + grid[i][j]\}
58+
$$
59+
60+
where $\text{moveCost}[grid[i - 1][k]][j]$ represents the cost of moving from the $k$th column of the $i - 1$th row to the $j$th column of the $i$th row.
61+
62+
The final answer is $\min_{0 \leq j < n} \{f[m - 1][j]\}$.
63+
64+
Since each transition only needs the state of the previous row, we can use a rolling array to optimize the space complexity to $O(n)$.
65+
66+
The time complexity is $O(m \times n^2)$, and the space complexity is $O(n)$. Here, $m$ and $n$ are the number of rows and columns of the grid, respectively.
67+
5268
<!-- tabs:start -->
5369

5470
### **Python3**
@@ -144,25 +160,21 @@ func minPathCost(grid [][]int, moveCost [][]int) int {
144160
```rust
145161
impl Solution {
146162
pub fn min_path_cost(grid: Vec<Vec<i32>>, move_cost: Vec<Vec<i32>>) -> i32 {
147-
let (m, n) = (grid.len(), grid[0].len());
148-
let mut dp = vec![0; n];
149-
for i in 0..m - 1 {
150-
let mut counter = vec![i32::MAX; n];
163+
let m = grid.len();
164+
let n = grid[0].len();
165+
let mut f = grid[0].clone();
166+
167+
for i in 1..m {
168+
let mut g: Vec<i32> = vec![i32::MAX; n];
151169
for j in 0..n {
152-
let val = grid[i][j];
153170
for k in 0..n {
154-
counter[k] = counter[k].min(val + move_cost[val as usize][k] + dp[j]);
171+
g[j] = g[j].min(f[k] + move_cost[grid[i - 1][k] as usize][j] + grid[i][j]);
155172
}
156173
}
157-
for j in 0..n {
158-
dp[j] = counter[j];
159-
}
174+
f.copy_from_slice(&g);
160175
}
161-
let mut res = i32::MAX;
162-
for i in 0..n {
163-
res = res.min(dp[i] + grid[m - 1][i]);
164-
}
165-
res
176+
177+
f.iter().cloned().min().unwrap_or(0)
166178
}
167179
}
168180
```
@@ -171,23 +183,19 @@ impl Solution {
171183

172184
```ts
173185
function minPathCost(grid: number[][], moveCost: number[][]): number {
174-
const m = grid.length,
175-
n = grid[0].length;
176-
let pre = grid[0].slice();
177-
for (let i = 1; i < m; i++) {
178-
let next = new Array(n);
179-
for (let j = 0; j < n; j++) {
180-
const key = grid[i - 1][j];
181-
for (let k = 0; k < n; k++) {
182-
let sum = pre[j] + moveCost[key][k] + grid[i][k];
183-
if (j == 0 || next[k] > sum) {
184-
next[k] = sum;
185-
}
186+
const m = grid.length;
187+
const n = grid[0].length;
188+
const f = grid[0];
189+
for (let i = 1; i < m; ++i) {
190+
const g: number[] = Array(n).fill(Infinity);
191+
for (let j = 0; j < n; ++j) {
192+
for (let k = 0; k < n; ++k) {
193+
g[j] = Math.min(g[j], f[k] + moveCost[grid[i - 1][k]][j] + grid[i][j]);
186194
}
187195
}
188-
pre = next;
196+
f.splice(0, n, ...g);
189197
}
190-
return Math.min(...pre);
198+
return Math.min(...f);
191199
}
192200
```
193201

Original file line numberDiff line numberDiff line change
@@ -1,23 +1,19 @@
11
impl Solution {
22
pub fn min_path_cost(grid: Vec<Vec<i32>>, move_cost: Vec<Vec<i32>>) -> i32 {
3-
let (m, n) = (grid.len(), grid[0].len());
4-
let mut dp = vec![0; n];
5-
for i in 0..m - 1 {
6-
let mut counter = vec![i32::MAX; n];
3+
let m = grid.len();
4+
let n = grid[0].len();
5+
let mut f = grid[0].clone();
6+
7+
for i in 1..m {
8+
let mut g: Vec<i32> = vec![i32::MAX; n];
79
for j in 0..n {
8-
let val = grid[i][j];
910
for k in 0..n {
10-
counter[k] = counter[k].min(val + move_cost[val as usize][k] + dp[j]);
11+
g[j] = g[j].min(f[k] + move_cost[grid[i - 1][k] as usize][j] + grid[i][j]);
1112
}
1213
}
13-
for j in 0..n {
14-
dp[j] = counter[j];
15-
}
16-
}
17-
let mut res = i32::MAX;
18-
for i in 0..n {
19-
res = res.min(dp[i] + grid[m - 1][i]);
14+
f.copy_from_slice(&g);
2015
}
21-
res
16+
17+
f.iter().cloned().min().unwrap_or(0)
2218
}
2319
}
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,15 @@
11
function minPathCost(grid: number[][], moveCost: number[][]): number {
2-
const m = grid.length,
3-
n = grid[0].length;
4-
let pre = grid[0].slice();
5-
for (let i = 1; i < m; i++) {
6-
let next = new Array(n);
7-
for (let j = 0; j < n; j++) {
8-
const key = grid[i - 1][j];
9-
for (let k = 0; k < n; k++) {
10-
let sum = pre[j] + moveCost[key][k] + grid[i][k];
11-
if (j == 0 || next[k] > sum) {
12-
next[k] = sum;
13-
}
2+
const m = grid.length;
3+
const n = grid[0].length;
4+
const f = grid[0];
5+
for (let i = 1; i < m; ++i) {
6+
const g: number[] = Array(n).fill(Infinity);
7+
for (let j = 0; j < n; ++j) {
8+
for (let k = 0; k < n; ++k) {
9+
g[j] = Math.min(g[j], f[k] + moveCost[grid[i - 1][k]][j] + grid[i][j]);
1410
}
1511
}
16-
pre = next;
12+
f.splice(0, n, ...g);
1713
}
18-
return Math.min(...pre);
14+
return Math.min(...f);
1915
}

0 commit comments

Comments
 (0)