# 1263. Minimum Moves to Move a Box to Their Target Location
###### tags: `Leetcode` `Hard` `BFS` `DFS`
Link: https://leetcode.com/problems/minimum-moves-to-move-a-box-to-their-target-location/description/
## 思路
思路[参考](https://leetcode.com/problems/minimum-moves-to-move-a-box-to-their-target-location/solutions/709355/java-use-2-level-bfs-beat-99/)
可以想到的是用bfs解决这个问题
但是问题是
1. 我们要保证人有位置可以推box 并且从现在人站的位置到推box的位置是有路可以走的 所以这时我们就需要另外一个bfs来判断有没有路可以走
2. 由于我们是不能跨越盒子的所以在里面这个bfs我们要把盒子当作一个block(通过把目前放盒子的点的visited设成true)
3. 2d的visited array是不够的 因为盒子会移动 所以可能在某个位置原本向左是走不通的但现在是可以的
## Code
```java=
class Solution {
public int minPushBox(char[][] grid) {
int m = grid.length, n = grid[0].length;
int[] start = new int[2];
int[] end = new int[2];
int[] ppl = new int[2];
int[][] dirs = new int[][]{{-1,0},{1,0},{0,1},{0,-1}};
for(int i=0; i<m; i++){
for(int j=0; j<n; j++){
if(grid[i][j]=='T') end = new int[]{i,j};
else if(grid[i][j]=='S') ppl = new int[]{i,j};
else if(grid[i][j]=='B') start = new int[]{i,j};
}
}
boolean[][][] visited = new boolean[m][n][4];
Queue<int[]> q = new LinkedList<>();
q.add(new int[]{start[0], start[1], ppl[0], ppl[1]});
int step = 0;
while(!q.isEmpty()){
int size = q.size();
for(int i=0; i<size; i++){
int[] curr = q.poll();
if(curr[0]==end[0] && curr[1]==end[1]) return step;
for(int j=0; j<dirs.length; j++){
if(visited[curr[0]][curr[1]][j]) continue;
int[] dir = dirs[j];
int r0 = curr[0]+dir[0], c0 = curr[1]+dir[1];
if(r0<0 || r0>=m || c0<0 || c0>=n || grid[r0][c0]=='#') continue;
int nextx = curr[0]-dir[0], nexty = curr[1]-dir[1];
if(nextx<0 || nextx>=m || nexty<0 || nexty>=n || grid[nextx][nexty]=='#') continue;
if(!canReach(r0, c0, curr, grid)) continue;
visited[curr[0]][curr[1]][j] = true;
q.add(new int[]{nextx, nexty, r0, c0});
}
}
step++;
}
return -1;
}
private boolean canReach(int r, int c, int[] pos, char[][] grid){
int x = pos[2], y = pos[3];
int m = grid.length, n = grid[0].length;
boolean[][] visited = new boolean[m][n];
visited[x][y] = true;
visited[pos[0]][pos[1]] = true;
Queue<int[]> q = new LinkedList<>();
int[][] dirs = new int[][]{{1,0},{-1,0},{0,1},{0,-1}};
q.add(new int[]{x,y});
while(!q.isEmpty()){
int[] curr = q.poll();
if(curr[0]==r && curr[1]==c) return true;
for(int[] dir:dirs){
int nextx = curr[0]+dir[0];
int nexty = curr[1]+dir[1];
if(nextx>=0 && nextx<m && nexty>=0 && nexty<n && !visited[nextx][nexty] && grid[nextx][nexty]!='#'){
q.add(new int[]{nextx, nexty});
visited[nextx][nexty] = true;
}
}
}
return false;
}
}
```