Hard
In an n*n
grid, there is a snake that spans 2 cells and starts moving from the top left corner at (0, 0)
and (0, 1)
. The grid has empty cells represented by zeros and blocked cells represented by ones. The snake wants to reach the lower right corner at (n-1, n-2)
and (n-1, n-1)
.
In one move the snake can:
(r, c)
and (r, c+1)
to (r, c)
and (r+1, c)
.(r, c)
and (r+1, c)
to (r, c)
and (r, c+1)
.Return the minimum number of moves to reach the target.
If there is no way to reach the target, return -1
.
Example 1:
Input:
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]]
Output: 11
Explanation: One possible solution is [right, right, rotate clockwise, right, down, down, down, down, rotate counterclockwise, right, down].
Example 2:
Input:
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]]
Output: 9
Constraints:
2 <= n <= 100
0 <= grid[i][j] <= 1
import java.util.LinkedList;
import java.util.Objects;
import java.util.Queue;
public class Solution {
public int minimumMoves(int[][] grid) {
int n = grid.length;
int[][] visited = new int[n][n];
Queue<int[]> bq = new LinkedList<>();
bq.offer(new int[] {0, 0, 1});
visited[0][0] |= 1;
int level = 0;
while (!bq.isEmpty()) {
int levelSize = bq.size();
for (int l = 0; l < levelSize; l++) {
int[] cur = bq.poll();
int xtail = Objects.requireNonNull(cur)[0];
int ytail = cur[1];
int dir = cur[2];
if (xtail == n - 1 && ytail == n - 2 && dir == 1) {
return level;
}
int xhead = xtail + (dir == 1 ? 0 : 1);
int yhead = ytail + (dir == 1 ? 1 : 0);
if (dir == 2) {
if (ytail + 1 < n
&& grid[xtail][ytail + 1] != 1
&& grid[xtail + 1][ytail + 1] != 1) {
if ((visited[xtail][ytail] & 1) == 0) {
bq.offer(new int[] {xtail, ytail, 1});
visited[xtail][ytail] |= 1;
}
if ((visited[xtail][ytail + 1] & 2) == 0) {
bq.offer(new int[] {xtail, ytail + 1, 2});
visited[xtail][ytail + 1] |= 2;
}
}
if (xhead + 1 < n
&& grid[xhead + 1][yhead] != 1
&& (visited[xhead][yhead] & 2) == 0) {
bq.offer(new int[] {xhead, yhead, 2});
visited[xhead][yhead] |= 2;
}
} else {
if (xtail + 1 < n
&& grid[xtail + 1][ytail] != 1
&& grid[xtail + 1][ytail + 1] != 1) {
if ((visited[xtail][ytail] & 2) == 0) {
bq.offer(new int[] {xtail, ytail, 2});
visited[xtail][ytail] |= 2;
}
if ((visited[xtail + 1][ytail] & 1) == 0) {
bq.offer(new int[] {xtail + 1, ytail, 1});
visited[xtail + 1][ytail] |= 1;
}
}
if (yhead + 1 < n
&& grid[xhead][yhead + 1] != 1
&& (visited[xhead][yhead] & 1) == 0) {
bq.offer(new int[] {xhead, yhead, 1});
visited[xhead][yhead] |= 1;
}
}
}
level += 1;
}
return -1;
}
}