Approach
Breadth-first search
For Minimum Moves to Move a Box to Their Target Location, the implementation explores reachable states in layers, which is the standard shape for unweighted shortest paths and minimum-step transitions.
- Model each valid configuration as a state and each legal move as an edge.
- Seed the queue with the starting state and mark it immediately.
- Expand each state once, recording distance or reachability for unseen neighbours.
Code notes
- 88 lines of Java from the credited upstream file 1263.java.
- The implementation visibly relies on sequence storage, work queue.
- 7 loop blocks detected.
Complexity
Verify that each state and transition is processed only a bounded number of times; that determines the traversal cost.
Check the problem constraints before deciding whether this complexity will pass.
Use this to learn the idea, then write your own version.
1class Solution {2 public int minPushBox(char[][] grid) {3 record T(int boxX, int boxY, int playerX, int playerY) {}4 final int m = grid.length;5 final int n = grid[0].length;6 int[] box = {-1, -1};7 int[] player = {-1, -1};8 int[] target = {-1, -1};9 10 for (int i = 0; i < m; ++i)11 for (int j = 0; j < n; ++j)12 if (grid[i][j] == 'B')13 box = new int[] {i, j};14 else if (grid[i][j] == 'S')15 player = new int[] {i, j};16 else if (grid[i][j] == 'T')17 target = new int[] {i, j};18 19 Queue<T> q = new ArrayDeque<>(List.of(new T(box[0], box[1], player[0], player[1])));20 boolean[][][][] seen = new boolean[m][n][m][n];21 seen[box[0]][box[1]][player[0]][player[1]] = true;22 23 for (int step = 0; !q.isEmpty(); ++step)24 for (int sz = q.size(); sz > 0; --sz) {25 final int boxX = q.peek().boxX;26 final int boxY = q.peek().boxY;27 final int playerX = q.peek().playerX;28 final int playerY = q.poll().playerY;29 if (boxX == target[0] && boxY == target[1])30 return step;31 for (int k = 0; k < 4; ++k) {32 final int nextBoxX = boxX + DIRS[k][0];33 final int nextBoxY = boxY + DIRS[k][1];34 if (isInvalid(grid, nextBoxX, nextBoxY))35 continue;36 if (seen[nextBoxX][nextBoxY][boxX][boxY])37 continue;38 final int fromX = boxX + DIRS[(k + 2) % 4][0];39 final int fromY = boxY + DIRS[(k + 2) % 4][1];40 if (isInvalid(grid, fromX, fromY))41 continue;42 if (canGoTo(grid, playerX, playerY, fromX, fromY, boxX, boxY)) {43 seen[nextBoxX][nextBoxY][boxX][boxY] = true;44 q.offer(new T(nextBoxX, nextBoxY, boxX, boxY));45 }46 }47 }48 49 return -1;50 }51 52 private static final int[][] DIRS = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};53 54 55 private boolean canGoTo(char[][] grid, int playerX, int playerY, int fromX, int fromY, int boxX,56 int boxY) {57 Queue<Pair<Integer, Integer>> q = new ArrayDeque<>(List.of(new Pair<>(playerX, playerY)));58 boolean[][] seen = new boolean[grid.length][grid[0].length];59 seen[playerX][playerY] = true;60 61 while (!q.isEmpty()) {62 final int i = q.peek().getKey();63 final int j = q.poll().getValue();64 if (i == fromX && j == fromY)65 return true;66 for (int[] dir : DIRS) {67 final int x = i + dir[0];68 final int y = j + dir[1];69 if (isInvalid(grid, x, y))70 continue;71 if (seen[x][y])72 continue;73 if (x == boxX && y == boxY)74 continue;75 q.offer(new Pair<>(x, y));76 seen[x][y] = true;77 }78 }79 80 return false;81 }82 83 private boolean isInvalid(char[][] grid, int playerX, int playerY) {84 return playerX < 0 || playerX == grid.length || playerY < 0 || playerY == grid[0].length ||85 grid[playerX][playerY] == '#';86 }87}88