Skip to content

Commit b2c7c21

Browse files
authored
feat: add solutions to lc problem: No.1810 (#4881)
1 parent ae35e0e commit b2c7c21

File tree

6 files changed

+774
-214
lines changed

6 files changed

+774
-214
lines changed

solution/1800-1899/1810.Minimum Path Cost in a Hidden Grid/README.md

Lines changed: 263 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,12 @@ tags:
116116

117117
### 方法一:DFS 建图 + 堆优化版 Dijkstra 算法
118118

119+
我们注意到,网格的大小为 $m \times n$,其中 $m, n \leq 100$。因此,我们可以初始化起点坐标 $(sx, sy) = (100, 100)$,并假设网格的大小为 $200 \times 200$。然后,我们可以使用深度优先搜索(DFS)来探索整个网格,并构建一个表示网格的二维数组 $g$,其中 $g[i][j]$ 表示从起点 $(sx, sy)$ 到坐标 $(i, j)$ 的移动消耗。如果某个单元格不可达,则将其值设为 $-1$。我们将终点坐标存储在 $\textit{target}$ 中,如果无法到达终点,则 $\textit{target} = (-1, -1)$。
120+
121+
接下来,我们可以使用堆优化版的 Dijkstra 算法来计算从起点 $(sx, sy)$ 到终点 $\textit{target}$ 的最小消耗路径。我们使用一个优先队列来存储当前的路径消耗和坐标,并使用一个二维数组 $\textit{dist}$ 来记录从起点到每个单元格的最小消耗。当我们从优先队列中取出一个节点时,如果该节点是终点,则返回当前的路径消耗作为答案。如果该节点的路径消耗大于 $\textit{dist}$ 中记录的值,则跳过该节点。否则,我们遍历该节点的四个邻居,如果邻居可达且通过该节点到达邻居的路径消耗更小,则更新邻居的路径消耗并将其加入优先队列。
122+
123+
时间复杂度 $O(m \times n \log(m \times n))$,空间复杂度 $O(m \times n)$。其中 $m$ 和 $n$ 分别是网格的行数和列数。
124+
119125
<!-- tabs:start -->
120126

121127
#### Python3
@@ -132,55 +138,57 @@ tags:
132138
# def move(self, direction: str) -> int:
133139
#
134140
#
135-
# def isTarget(self) -> None:
141+
# def isTarget(self) -> bool:
136142
#
137143
#
138144

139145

140146
class Solution(object):
141-
def findShortestPath(self, master: 'GridMaster') -> int:
142-
def dfs(i, j):
147+
def findShortestPath(self, master: "GridMaster") -> int:
148+
def dfs(x: int, y: int) -> None:
143149
nonlocal target
144150
if master.isTarget():
145-
target = (i, j)
146-
for dir, (a, b, ndir) in dirs.items():
147-
x, y = i + a, j + b
148-
if 0 <= x < N and 0 <= y < N and master.canMove(dir) and g[x][y] == -1:
149-
g[x][y] = master.move(dir)
150-
dfs(x, y)
151-
master.move(ndir)
152-
151+
target = (x, y)
152+
for k in range(4):
153+
dx, dy = dirs[k], dirs[k + 1]
154+
nx, ny = x + dx, y + dy
155+
if (
156+
0 <= nx < m
157+
and 0 <= ny < n
158+
and g[nx][ny] == -1
159+
and master.canMove(s[k])
160+
):
161+
g[nx][ny] = master.move(s[k])
162+
dfs(nx, ny)
163+
master.move(s[(k + 2) % 4])
164+
165+
dirs = (-1, 0, 1, 0, -1)
166+
s = "URDL"
167+
m = n = 200
168+
g = [[-1] * n for _ in range(m)]
153169
target = (-1, -1)
154-
N = 200
155-
INF = 0x3F3F3F3F
156-
g = [[-1] * N for _ in range(N)]
157-
dirs = {
158-
'U': (-1, 0, 'D'),
159-
'D': (1, 0, 'U'),
160-
'L': (0, -1, 'R'),
161-
'R': (0, 1, 'L'),
162-
}
163-
dfs(100, 100)
170+
sx = sy = 100
171+
dfs(sx, sy)
164172
if target == (-1, -1):
165173
return -1
166-
q = [(0, 100, 100)]
167-
dist = [[INF] * N for _ in range(N)]
168-
dist[100][100] = 0
169-
while q:
170-
w, i, j = heappop(q)
171-
if (i, j) == target:
174+
pq = [(0, sx, sy)]
175+
dist = [[inf] * n for _ in range(m)]
176+
dist[sx][sy] = 0
177+
while pq:
178+
w, x, y = heappop(pq)
179+
if (x, y) == target:
172180
return w
173-
for a, b, _ in dirs.values():
174-
x, y = i + a, j + b
181+
for dx, dy in pairwise(dirs):
182+
nx, ny = x + dx, y + dy
175183
if (
176-
0 <= x < N
177-
and 0 <= y < N
178-
and g[x][y] != -1
179-
and dist[x][y] > w + g[x][y]
184+
0 <= nx < m
185+
and 0 <= ny < n
186+
and g[nx][ny] != -1
187+
and w + g[nx][ny] < dist[nx][ny]
180188
):
181-
dist[x][y] = w + g[x][y]
182-
heappush(q, (dist[x][y], x, y))
183-
return 0
189+
dist[nx][ny] = w + g[nx][ny]
190+
heappush(pq, (dist[nx][ny], nx, ny))
191+
return -1
184192
```
185193

186194
#### Java
@@ -197,63 +205,247 @@ class Solution(object):
197205
*/
198206

199207
class Solution {
200-
private static final char[] dir = {'U', 'R', 'D', 'L'};
201-
private static final char[] ndir = {'D', 'L', 'U', 'R'};
202-
private static final int[] dirs = {-1, 0, 1, 0, -1};
203-
private static final int N = 200;
204-
private static final int INF = 0x3f3f3f3f;
205-
private static int[][] g = new int[N][N];
206-
private static int[][] dist = new int[N][N];
207-
private int[] target;
208+
private final int m = 200;
209+
private final int n = 200;
210+
private final int inf = Integer.MAX_VALUE / 2;
211+
private final int[] dirs = {-1, 0, 1, 0, -1};
212+
private final char[] s = {'U', 'R', 'D', 'L'};
213+
private int[][] g;
214+
private int sx = 100, sy = 100;
215+
private int tx = -1, ty = -1;
216+
private GridMaster master;
208217

209218
public int findShortestPath(GridMaster master) {
210-
target = new int[] {-1, -1};
211-
for (int i = 0; i < N; ++i) {
212-
Arrays.fill(g[i], -1);
213-
Arrays.fill(dist[i], INF);
219+
this.master = master;
220+
g = new int[m][n];
221+
for (var gg : g) {
222+
Arrays.fill(gg, -1);
214223
}
215-
dfs(100, 100, master);
216-
if (target[0] == -1 && target[1] == -1) {
224+
dfs(sx, sy);
225+
if (tx == -1 && ty == -1) {
217226
return -1;
218227
}
219-
PriorityQueue<int[]> q = new PriorityQueue<>(Comparator.comparingInt(a -> a[0]));
220-
q.offer(new int[] {0, 100, 100});
221-
dist[100][100] = 0;
222-
while (!q.isEmpty()) {
223-
int[] p = q.poll();
224-
int w = p[0], i = p[1], j = p[2];
225-
if (i == target[0] && j == target[1]) {
228+
PriorityQueue<int[]> pq = new PriorityQueue<>((a, b) -> a[0] - b[0]);
229+
pq.offer(new int[] {0, sx, sy});
230+
int[][] dist = new int[m][n];
231+
for (var gg : dist) {
232+
Arrays.fill(gg, inf);
233+
}
234+
dist[sx][sy] = 0;
235+
while (!pq.isEmpty()) {
236+
var p = pq.poll();
237+
int w = p[0], x = p[1], y = p[2];
238+
if (x == tx && y == ty) {
226239
return w;
227240
}
241+
if (w > dist[x][y]) {
242+
continue;
243+
}
228244
for (int k = 0; k < 4; ++k) {
229-
int x = i + dirs[k], y = j + dirs[k + 1];
230-
if (x >= 0 && x < N && y >= 0 && y < N && g[x][y] != -1
231-
&& dist[x][y] > w + g[x][y]) {
232-
dist[x][y] = w + g[x][y];
233-
q.offer(new int[] {dist[x][y], x, y});
245+
int nx = x + dirs[k], ny = y + dirs[k + 1];
246+
if (nx >= 0 && nx < m && ny >= 0 && ny < n && g[nx][ny] != -1
247+
&& w + g[nx][ny] < dist[nx][ny]) {
248+
dist[nx][ny] = w + g[nx][ny];
249+
pq.offer(new int[] {dist[nx][ny], nx, ny});
234250
}
235251
}
236252
}
237-
return 0;
253+
return -1;
238254
}
239255

240-
private void dfs(int i, int j, GridMaster master) {
256+
private void dfs(int x, int y) {
241257
if (master.isTarget()) {
242-
target = new int[] {i, j};
258+
tx = x;
259+
ty = y;
243260
}
244261
for (int k = 0; k < 4; ++k) {
245-
char d = dir[k], nd = ndir[k];
246-
int x = i + dirs[k], y = j + dirs[k + 1];
247-
if (x >= 0 && x < N && y >= 0 && y < N && master.canMove(d) && g[x][y] == -1) {
248-
g[x][y] = master.move(d);
249-
dfs(x, y, master);
250-
master.move(nd);
262+
int dx = dirs[k], dy = dirs[k + 1];
263+
int nx = x + dx, ny = y + dy;
264+
if (nx >= 0 && nx < m && ny >= 0 && ny < n && g[nx][ny] == -1 && master.canMove(s[k])) {
265+
g[nx][ny] = master.move(s[k]);
266+
dfs(nx, ny);
267+
master.move(s[(k + 2) % 4]);
251268
}
252269
}
253270
}
254271
}
255272
```
256273

274+
#### C++
275+
276+
```cpp
277+
/**
278+
* // This is the GridMaster's API interface.
279+
* // You should not implement it, or speculate about its implementation
280+
* class GridMaster {
281+
* public:
282+
* bool canMove(char direction);
283+
* int move(char direction);
284+
* boolean isTarget();
285+
* };
286+
*/
287+
288+
class Solution {
289+
public:
290+
int findShortestPath(GridMaster& master) {
291+
const int m = 200, n = 200;
292+
const int sx = 100, sy = 100;
293+
const int INF = INT_MAX / 2;
294+
int dirs[5] = {-1, 0, 1, 0, -1};
295+
char s[4] = {'U', 'R', 'D', 'L'};
296+
297+
vector<vector<int>> g(m, vector<int>(n, -1));
298+
pair<int, int> target = {-1, -1};
299+
300+
auto dfs = [&](this auto& dfs, int x, int y) -> void {
301+
if (master.isTarget()) {
302+
target = {x, y};
303+
}
304+
for (int k = 0; k < 4; ++k) {
305+
int dx = dirs[k], dy = dirs[k + 1];
306+
int nx = x + dx, ny = y + dy;
307+
if (0 <= nx && nx < m && 0 <= ny && ny < n && g[nx][ny] == -1 && master.canMove(s[k])) {
308+
g[nx][ny] = master.move(s[k]);
309+
dfs(nx, ny);
310+
master.move(s[(k + 2) % 4]);
311+
}
312+
}
313+
};
314+
315+
g[sx][sy] = 0;
316+
dfs(sx, sy);
317+
318+
if (target.first == -1 && target.second == -1) {
319+
return -1;
320+
}
321+
322+
vector<vector<int>> dist(m, vector<int>(n, INF));
323+
dist[sx][sy] = 0;
324+
325+
using Node = tuple<int, int, int>;
326+
priority_queue<Node, vector<Node>, greater<Node>> pq;
327+
pq.emplace(0, sx, sy);
328+
329+
while (!pq.empty()) {
330+
auto [w, x, y] = pq.top();
331+
pq.pop();
332+
if (x == target.first && y == target.second) {
333+
return w;
334+
}
335+
if (w > dist[x][y]) {
336+
continue;
337+
}
338+
339+
for (int k = 0; k < 4; ++k) {
340+
int nx = x + dirs[k], ny = y + dirs[k + 1];
341+
if (0 <= nx && nx < m && 0 <= ny && ny < n && g[nx][ny] != -1) {
342+
int nd = w + g[nx][ny];
343+
if (nd < dist[nx][ny]) {
344+
dist[nx][ny] = nd;
345+
pq.emplace(nd, nx, ny);
346+
}
347+
}
348+
}
349+
}
350+
351+
return -1;
352+
}
353+
};
354+
```
355+
356+
#### JavaScript
357+
358+
```js
359+
/**
360+
* // This is the GridMaster's API interface.
361+
* // You should not implement it, or speculate about its implementation
362+
* function GridMaster() {
363+
*
364+
* @param {character} direction
365+
* @return {boolean}
366+
* this.canMove = function(direction) {
367+
* ...
368+
* };
369+
* @param {character} direction
370+
* @return {integer}
371+
* this.move = function(direction) {
372+
* ...
373+
* };
374+
* @return {boolean}
375+
* this.isTarget = function() {
376+
* ...
377+
* };
378+
* };
379+
*/
380+
381+
/**
382+
* @param {GridMaster} master
383+
* @return {integer}
384+
*/
385+
var findShortestPath = function (master) {
386+
const [m, n] = [200, 200];
387+
const [sx, sy] = [100, 100];
388+
const inf = Number.MAX_SAFE_INTEGER;
389+
const dirs = [-1, 0, 1, 0, -1];
390+
const s = ['U', 'R', 'D', 'L'];
391+
const g = Array.from({ length: m }, () => Array(n).fill(-1));
392+
let target = [-1, -1];
393+
const dfs = (x, y) => {
394+
if (master.isTarget()) {
395+
target = [x, y];
396+
}
397+
for (let k = 0; k < 4; ++k) {
398+
const dx = dirs[k],
399+
dy = dirs[k + 1];
400+
const nx = x + dx,
401+
ny = y + dy;
402+
if (
403+
0 <= nx &&
404+
nx < m &&
405+
0 <= ny &&
406+
ny < n &&
407+
g[nx][ny] === -1 &&
408+
master.canMove(s[k])
409+
) {
410+
g[nx][ny] = master.move(s[k]);
411+
dfs(nx, ny);
412+
master.move(s[(k + 2) % 4]);
413+
}
414+
}
415+
};
416+
g[sx][sy] = 0;
417+
dfs(sx, sy);
418+
if (target[0] === -1 && target[1] === -1) {
419+
return -1;
420+
}
421+
const dist = Array.from({ length: m }, () => Array(n).fill(inf));
422+
dist[sx][sy] = 0;
423+
const pq = new MinPriorityQueue(node => node[0]);
424+
pq.enqueue([0, sx, sy]);
425+
while (!pq.isEmpty()) {
426+
const [w, x, y] = pq.dequeue();
427+
if (x === target[0] && y === target[1]) {
428+
return w;
429+
}
430+
if (w > dist[x][y]) {
431+
continue;
432+
}
433+
for (let k = 0; k < 4; ++k) {
434+
const nx = x + dirs[k],
435+
ny = y + dirs[k + 1];
436+
if (0 <= nx && nx < m && 0 <= ny && ny < n && g[nx][ny] !== -1) {
437+
const nd = w + g[nx][ny];
438+
if (nd < dist[nx][ny]) {
439+
dist[nx][ny] = nd;
440+
pq.enqueue([nd, nx, ny]);
441+
}
442+
}
443+
}
444+
}
445+
return -1;
446+
};
447+
```
448+
257449
<!-- tabs:end -->
258450

259451
<!-- solution:end -->

0 commit comments

Comments
 (0)