你还记得那条风靡全球的贪吃蛇吗?
我们在一个 n*n
的网格上构建了新的迷宫地图,蛇的长度为 2,也就是说它会占去两个单元格。蛇会从左上角((0, 0)
和 (0, 1)
)开始移动。我们用 0
表示空单元格,用 1 表示障碍物。蛇需要移动到迷宫的右下角((n-1, n-2)
和 (n-1, n-1)
)。
每次移动,蛇可以这样走:
(r, c)
、(r, c+1)
)移动到 ((r, c)
、(r+1, c)
)。(r, c)
、(r+1, c)
)移动到((r, c)
、(r, c+1)
)。返回蛇抵达目的地所需的最少移动次数。
如果无法到达目的地,请返回 -1
。
示例 1:
输入:grid = [[0,0,0,0,0,1],
[1,1,0,0,1,0],
[0,0,0,0,1,1],
[0,0,1,0,1,0],
[0,1,1,0,0,0],
[0,1,1,0,0,0]]
输出:11
解释:
一种可能的解决方案是 [右, 右, 顺时针旋转, 右, 下, 下, 下, 下, 逆时针旋转, 右, 下]。
示例 2:
输入:grid = [[0,0,1,1,1,1],
[0,0,0,0,1,1],
[1,1,0,0,0,1],
[1,1,1,0,0,1],
[1,1,1,0,0,1],
[1,1,1,0,0,0]]
输出:9
提示:
2 <= n <= 100
0 <= grid[i][j] <= 1
思路:
问最短距离就上BFS。
本题实质就是BFS找最短路径,但难在移动的方向很多,
1. 如果当前水平,则可以向下,向右,旋转
2. 如果当前水平,则可以向下,向右,旋转
思路不难,但是实现起来需要细心。
class Solution(object):
def minimumMoves(self, grid):
"""
:type grid: List[List[int]]
:rtype: int
"""
n = len(grid)
from collections import deque
queue = deque([((0, 0), (0, 1), 0)])
visited = set()
while queue:
pos0, pos1, step = queue.popleft()
# print pos0, pos1
x0, y0 = pos0
x1, y1 = pos1
if (x0, y0) == (n - 1, n - 2) and (x1, y1) == (n - 1, n - 1):
return step
if x0 == x1 and y1 > y0:# 水平
# 向右走
x2, y2 = x1, y1 + 1
if 0 <= x2 < n and 0 <= y2 < n and ((x1, y1), (x2, y2)) not in visited and grid[x2][y2] != 1:
visited.add(((x1, y1), (x2, y2)))
queue.append(((x1, y1), (x2, y2), step + 1))
# 向下走
x2, y2 = x0 + 1, y0
x3, y3 = x1 + 1, y1
if 0 <= x2 < n and 0 <= x3 < n and 0 <= x3 < n and 0 <= y3 < n and ((x2, y2), (x3, y3)) not in visited and grid[x2][y2] != 1 and grid[x3][y3] != 1:
visited.add(((x2, y2), (x3, y3)))
queue.append(((x2, y2), (x3, y3), step + 1))
# 旋转
x2, y2 = x0 + 1, y0
if 0 <= x2 < n and 0 <= y2 < n and ((x0, y0), (x2, y2)) not in visited and grid[x0 + 1][y0] != 1 and grid[x0 + 1][y0 + 1] != 1:
visited.add(((x0, y0), (x2, y2)))
queue.append(((x0, y0), (x2, y2), step + 1))
elif x1 > x0 and y0 == y1:#竖直
#向右走
x2, y2 = x0, y0 + 1
x3, y3 = x1, y1 + 1
if 0 <= x2 < n and 0 <= x3 < n and 0 <= x3 < n and 0 <= y3 < n and ((x2, y2), (x3, y3)) not in visited and grid[x2][y2] != 1 and grid[x3][y3] != 1:
visited.add(((x2, y2), (x3, y3)))
queue.append(((x2, y2), (x3, y3), step + 1))
#向下走
x2, y2 = x1 + 1, y1
if 0 <= x2 < n and 0 <= y2 < n and ((x1, y1), (x2, y2)) not in visited and grid[x2][y2] != 1:
visited.add(((x1, y1), (x2, y2)))
queue.append(((x1, y1), (x2, y2), step + 1))
# 旋转
x2, y2 = x0, y0 + 1
if 0 <= x2 < n and 0 <= y2 < n and ((x0, y0), (x2, y2)) not in visited and grid[x0][y0 + 1] != 1 and grid[x0 + 1][y0 + 1] != 1:
visited.add(((x0, y0), (x2, y2)))
queue.append(((x0, y0), (x2, y2), step + 1))
return -1