Java short and easy to understand BFS
We can treat the grid as 1d array and use the position as the identifiers. Introduce a hashset to check if the snake span is visisted with the format of first-s
We can treat the grid as 1d array and use the position as the identifiers. Introduce a hashset to check if the snake span is visisted with the format of `first-second`. The position of first and second cell of the span is x1, y1 and x2, y2 respectively. The move them as needed just like regular BFS.\n\ne.g. The positions of the grid in the example are 0 - 35, we add the span [0, 1] to queue, then move the snake right by one step to [1,2], then further right to [2, 3], now rotates clockwise to be [2, 2 + n] which is [2, 8]. At this point, the coordinates of the span is (0,2) (1,2) and the snake is heading down. Now move the snake to the right as a whole to [2 +1, 8 +1] which is [3, 9]. Then move down four times till the bottom of the grid to [27, 33]. Now the snake\'s coordinates is (27 / n = **4**, 27 % n = **3**) and (33 / n = **5**, 33 % n = **3**). rotate counter clockwise to [27, 27 +1], to the right [27 + 1, 28 +1], finally going down to [28 + n, 29 +n] which is [34, 35].\n\n```\nclass Solution {\n    public int minimumMoves(int[][] grid) {\n        int n = grid.length, moves = 0;\n        Queue<int[]> q = new LinkedList<>();\n        Set<String> seen = new HashSet<>();\n        q.offer(new int[] {0, 1});\n        seen.add("0-1");\n        \n        while (!q.isEmpty()) {\n            int size = q.size();\n            for (int i = 0; i < size; i++) {\n                int[] span = q.poll();\n                int first = span[0], second = span[1], x1 = first / n, y1 = first % n, x2 = second / n, y2 = second % n;\n                if (x1 == n - 1 && y1 == n - 2 && x2 == n - 1 && y2 == n - 1) return moves;\n                \n                if (x1 == x2) { // horizontal\n                    if (y2 + 1 < n && grid[x2][y2 + 1] == 0) move(q, second, second + 1, seen); // right\n                    if (x2 + 1 < n && grid[x1 + 1][y1] == 0 && grid[x2 + 1][y2] == 0) {\n                        move(q, first + n, second + n, seen); // down\n                        move(q, first, first + n, seen); // clockwise\n                    }\n                } \n                \n                if (y1 == y2) { // vertical\n                    if (x2 + 1 < n && grid[x2 + 1][y2] == 0) move(q, second, second + n, seen); // down\n                    if (y2 + 1 < n && grid[x1][y1 + 1] == 0 && grid[x2][y2 + 1] == 0) {\n                        move(q, first + 1, second + 1, seen); // right\n                        move(q, first, first + 1, seen); // counter clockwise\n                    }\n                } \n            }\n            moves++;\n        }\n        return -1;\n    }\n    \n    private void move(Queue<int[]> q, int first, int second, Set<String> seen) {\n        if (!seen.contains(first + "-" + second)) {\n            q.offer(new int[] { first, second });\n            seen.add(first + "-" + second);\n        }\n    }\n}\n```
[]