Skip to content

Commit b051ca2

Browse files
committed
Sync LeetCode submission Runtime - 5257 ms (23.43%), Memory - 154.8 MB (29.86%)
1 parent e1f1793 commit b051ca2

File tree

2 files changed

+164
-0
lines changed

2 files changed

+164
-0
lines changed
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
<p>This is an <strong>interactive problem</strong>.</p>
2+
3+
<p>There is a robot in a hidden grid, and you are trying to get it from its starting cell to the target cell in this grid. The grid is of size <code>m x n</code>, and each cell in the grid is either empty or blocked. It is <strong>guaranteed</strong> that the starting cell and the target cell are different, and neither of them is blocked.</p>
4+
5+
<p>You want to find the minimum distance to the target cell. However, you <strong>do not know</strong> the grid&#39;s dimensions, the starting cell, nor the target cell. You are only allowed to ask queries to the <code>GridMaster</code> object.</p>
6+
7+
<p>Thr <code>GridMaster</code> class has the following functions:</p>
8+
9+
<ul>
10+
<li><code>boolean canMove(char direction)</code> Returns <code>true</code> if the robot can move in that direction. Otherwise, it returns <code>false</code>.</li>
11+
<li><code>void move(char direction)</code> Moves the robot in that direction. If this move would move the robot to a blocked cell or off the grid, the move will be <strong>ignored</strong>, and the robot will remain in the same position.</li>
12+
<li><code>boolean isTarget()</code> Returns <code>true</code> if the robot is currently on the target cell. Otherwise, it returns <code>false</code>.</li>
13+
</ul>
14+
15+
<p>Note that <code>direction</code> in the above functions should be a character from <code>{&#39;U&#39;,&#39;D&#39;,&#39;L&#39;,&#39;R&#39;}</code>, representing the directions up, down, left, and right, respectively.</p>
16+
17+
<p>Return <em>the <strong>minimum distance</strong> between the robot&#39;s initial starting cell and the target cell. If there is no valid path between the cells, return </em><code>-1</code>.</p>
18+
19+
<p><strong>Custom testing:</strong></p>
20+
21+
<p>The test input is read as a 2D matrix <code>grid</code> of size <code>m x n</code> where:</p>
22+
23+
<ul>
24+
<li><code>grid[i][j] == -1</code> indicates that the robot is in cell <code>(i, j)</code> (the starting cell).</li>
25+
<li><code>grid[i][j] == 0</code> indicates that the cell <code>(i, j)</code> is blocked.</li>
26+
<li><code>grid[i][j] == 1</code> indicates that the cell <code>(i, j)</code> is empty.</li>
27+
<li><code>grid[i][j] == 2</code> indicates that the cell <code>(i, j)</code> is the target cell.</li>
28+
</ul>
29+
30+
<p>There is exactly one <code>-1</code> and <code>2</code> in <code>grid</code>. Remember that you will <strong>not</strong> have this information in your code.</p>
31+
32+
<p>&nbsp;</p>
33+
<p><strong class="example">Example 1:</strong></p>
34+
35+
<pre>
36+
<strong>Input:</strong> grid = [[1,2],[-1,0]]
37+
<strong>Output:</strong> 2
38+
<strong>Explanation:</strong> One possible interaction is described below:
39+
The robot is initially standing on cell (1, 0), denoted by the -1.
40+
- master.canMove(&#39;U&#39;) returns true.
41+
- master.canMove(&#39;D&#39;) returns false.
42+
- master.canMove(&#39;L&#39;) returns false.
43+
- master.canMove(&#39;R&#39;) returns false.
44+
- master.move(&#39;U&#39;) moves the robot to the cell (0, 0).
45+
- master.isTarget() returns false.
46+
- master.canMove(&#39;U&#39;) returns false.
47+
- master.canMove(&#39;D&#39;) returns true.
48+
- master.canMove(&#39;L&#39;) returns false.
49+
- master.canMove(&#39;R&#39;) returns true.
50+
- master.move(&#39;R&#39;) moves the robot to the cell (0, 1).
51+
- master.isTarget() returns true.
52+
We now know that the target is the cell (0, 1), and the shortest path to the target cell is 2.
53+
</pre>
54+
55+
<p><strong class="example">Example 2:</strong></p>
56+
57+
<pre>
58+
<strong>Input:</strong> grid = [[0,0,-1],[1,1,1],[2,0,0]]
59+
<strong>Output:</strong> 4
60+
<strong>Explanation:</strong>&nbsp;The minimum distance between the robot and the target cell is 4.</pre>
61+
62+
<p><strong class="example">Example 3:</strong></p>
63+
64+
<pre>
65+
<strong>Input:</strong> grid = [[-1,0],[0,2]]
66+
<strong>Output:</strong> -1
67+
<strong>Explanation:</strong>&nbsp;There is no path from the robot to the target cell.</pre>
68+
69+
<p>&nbsp;</p>
70+
<p><strong>Constraints:</strong></p>
71+
72+
<ul>
73+
<li><code>1 &lt;= n, m &lt;= 500</code></li>
74+
<li><code>m == grid.length</code></li>
75+
<li><code>n == grid[i].length</code></li>
76+
<li><code>grid[i][j]</code> is either <code>-1</code>, <code>0</code>, <code>1</code>, or <code>2</code>.</li>
77+
<li>There is <strong>exactly one</strong> <code>-1</code> in <code>grid</code>.</li>
78+
<li>There is <strong>exactly one</strong> <code>2</code> in <code>grid</code>.</li>
79+
</ul>
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# Approach: DFS + BFS
2+
3+
# Time: O(m * n)
4+
# Space: O(m * n)
5+
6+
# """
7+
# This is GridMaster's API interface.
8+
# You should not implement it, or speculate about its implementation
9+
# """
10+
#class GridMaster(object):
11+
# def canMove(self, direction: str) -> bool:
12+
#
13+
#
14+
# def move(self, direction: str) -> None:
15+
#
16+
#
17+
# def isTarget(self) -> bool:
18+
#
19+
#
20+
21+
class Solution(object):
22+
def findShortestPath(self, master: 'GridMaster') -> int:
23+
directions = {
24+
'U': (0, 1),
25+
'D': (0, -1),
26+
'L': (-1, 0),
27+
'R': (1, 0)
28+
}
29+
30+
opposite = {
31+
'U': 'D',
32+
'D': 'U',
33+
'L': 'R',
34+
'R': 'L'
35+
}
36+
37+
# Store all reachable cells and target location
38+
visited = set()
39+
target = None
40+
41+
# DFS to map the grid (Phase 1)
42+
def dfs(x, y):
43+
nonlocal target
44+
45+
visited.add((x, y))
46+
47+
if master.isTarget():
48+
target = (x, y)
49+
50+
for dir_char, (dx, dy) in directions.items():
51+
next_x, next_y = x + dx, y + dy
52+
53+
# If we can move in this direction and haven't visited the next cell
54+
if master.canMove(dir_char) and (next_x, next_y) not in visited:
55+
master.move(dir_char) # Move forward
56+
dfs(next_x, next_y) # Explore from new position
57+
master.move(opposite[dir_char]) # Move back
58+
59+
# Start DFS from (0, 0)
60+
dfs(0, 0)
61+
62+
# If target is not found, return -1
63+
if target is None:
64+
return -1
65+
66+
# BFS to find the shortest path to target (Phase 2)
67+
queue = [(0, 0, 0)] # (x, y, distance)
68+
visited_bfs = {(0, 0)}
69+
70+
while queue:
71+
x, y, dist = queue.pop(0)
72+
73+
if (x, y) == target:
74+
return dist
75+
76+
for dx, dy in directions.values():
77+
next_x, next_y = x + dx, y + dy
78+
79+
# Only consider cells that were found reachable in first phase (DFS)
80+
if (next_x, next_y) in visited and (next_x, next_y) not in visited_bfs:
81+
visited_bfs.add((next_x, next_y))
82+
queue.append((next_x, next_y, dist + 1))
83+
84+
return -1
85+

0 commit comments

Comments
 (0)