BFS with (box pos+ direction) as the state
\n\nclass Solution {\n    int m=0,n=0;\n    public int minPushBox(char[][] grid) {\n        m=grid.length;\n        n=grid[0].length;\n        int sx=0,sy=0,bx=
```\n\nclass Solution {\n    int m=0,n=0;\n    public int minPushBox(char[][] grid) {\n        m=grid.length;\n        n=grid[0].length;\n        int sx=0,sy=0,bx=0,by=0,tx=0,ty=0;\n        for(int i=0;i<m;i++) for(int j=0;j<n;j++){\n            if(grid[i][j]==\'S\'){sx=i;sy=j;grid[i][j]=\'.\';}\n            if(grid[i][j]==\'T\'){tx=i;ty=j;grid[i][j]=\'.\';}\n            if(grid[i][j]==\'B\'){bx=i;by=j;grid[i][j]=\'.\';}\n        }\n        \n        Queue<int[]> q=new LinkedList();\n        boolean[][][] visited=new boolean[m][n][4];\n        if(valid(grid,sx,sy,bx-1,by,bx,by)) {q.offer(new int[]{bx,by,0});visited[bx][by][0]=true;}\n        if(valid(grid,sx,sy,bx+1,by,bx,by)) {q.offer(new int[]{bx,by,1});visited[bx][by][1]=true;}\n        if(valid(grid,sx,sy,bx,by+1,bx,by)) {q.offer(new int[]{bx,by,2});visited[bx][by][2]=true;}\n        if(valid(grid,sx,sy,bx,by-1,bx,by)) {q.offer(new int[]{bx,by,3});visited[bx][by][3]=true;}\n        int depth=0;\n        while(!q.isEmpty()){\n            int size=q.size();\n            for(int i=0;i<size;i++){\n                int[] v=q.poll();\n                int[] d=trans(v[2]);\n                int x=v[0]-d[0],y=v[1]-d[1];//move one step x,y is new box position\n                //System.out.println(v[0]+"-"+v[1]+"##"+x+"-"+y+"");\n                if(x<0||x>m-1||y<0||y>n-1) continue;\n                if(grid[x][y]!=\'.\') continue;\n                if(x==tx&&y==ty) return depth+1;\n                //grid[v[0]][v[1]]=\'.\';\n                //grid[x][y]=\'B\';\n                for(int[] dir:dirs){\n                    if(valid(grid,v[0],v[1],x+dir[0],y+dir[1],x,y)) {\n                        int dd=transv(dir);\n                        if(visited[x][y][dd]) continue;\n                        visited[x][y][dd]=true;\n                        q.offer(new int[]{x,y,dd});\n                    }\n                }\n                //grid[x][y]=\'.\';\n                //grid[v[0]][v[1]]=\'B\';\n            }\n            depth++;\n        }\n        return -1;\n    }\n    \n    private boolean valid(char[][] graph,int sx,int sy,int tx,int ty,int bx,int by){\n        if(tx<0||tx>m-1||ty<0||ty>n-1) return false;\n        if(graph[tx][ty]!=\'.\') return false;\n        Queue<int[]> q=new LinkedList();\n        boolean[][] visited=new boolean[m][n];\n        q.offer(new int[]{sx,sy});visited[sx][sy]=true;\n        \n        while(!q.isEmpty()){\n            int size=q.size();\n            for(int i=0;i<size;i++){\n                int[] v=q.poll();\n                if(v[0]==tx&&v[1]==ty) return true;\n                for(int[] dir:dirs){\n                    int x=v[0]+dir[0],y=v[1]+dir[1];\n                    if(x<0||x>m-1||y<0||y>n-1) continue;\n                    if(graph[x][y]!=\'.\') continue;\n                    if(x==bx&&y==by) continue;\n                    if(visited[x][y]) continue;\n                    visited[x][y]=true;\n                    q.offer(new int[]{x,y});\n                }\n            }\n        \n        }\n        return false;\n    }\n    \n    \n    private int[][] dirs={{-1,0},{1,0},{0,1},{0,-1}};\n    private int[] trans(int dir){\n        int[] res=new int[2];\n        if(dir==0) res[0]=-1;\n        else if(dir==1) res[0]=1;\n        else if(dir==2) res[1]=1;\n        else res[1]=-1;\n        return res;\n    }\n    \n    private int transv(int[] dir){\n        if(dir[0]==-1) return 0;\n        else if(dir[0]==1) return 1;\n        else if(dir[1]==1) return 2;\n        else if(dir[1]==-1) return 3;\n        return -1;\n    }\n    \n}\n\n```
[]