Simple Java Solution -- Union Find & BFS
\nclass Solution {\n    //1. \u5E76\u67E5\u96C6\u5224\u65AD\u80FD\u5426\u5230\u8FBE\n    //2. BFS \u7BB1\u5B50\n    int[][] dir = new int[][]{{-1, 0}, {1, 0}, {
```\nclass Solution {\n    //1. \u5E76\u67E5\u96C6\u5224\u65AD\u80FD\u5426\u5230\u8FBE\n    //2. BFS \u7BB1\u5B50\n    int[][] dir = new int[][]{{-1, 0}, {1, 0}, {0, 1}, {0, -1}};\n    public int minPushBox(char[][] grid) {\n        int m = grid.length, n = grid[0].length;\n        int px = 0, py = 0, tx = 0, ty = 0, bx = 0, by = 0;\n        for(int i = 0; i < m; i++) {\n            for(int j = 0; j < n; j++) {\n                if(grid[i][j] == \'B\') {\n                    bx = i;\n                    by = j;\n                } else if(grid[i][j] == \'S\') {\n                    px = i;\n                    py = j;\n                } else if(grid[i][j] == \'T\') {\n                    tx = i;\n                    ty = j;\n                }\n            }\n        }\n        int[] parent = buildSet(grid, m, n);\n        int sp = find(parent, px * n + py);\n        int st = find(parent, tx * n + ty);\n        int sb = find(parent, bx * n + by);\n        if(!(sp == st && st == sb)) return -1;\n        \n        Queue<int[]> que = new LinkedList<>();\n        Set<String> visited = new HashSet<>();\n        que.offer(new int[]{bx * n + by, px * n + py});\n        visited.add((bx * n + by) + "," + (px * n + py));\n        \n        int res = 0;\n        while(!que.isEmpty()) {\n            for(int size = que.size(); size > 0; size--) {\n                int[] p = que.poll();\n                if(p[0] == tx * n + ty) return res;\n                int r = p[0] / n, c = p[0] % n;\n                \n                char ch = grid[r][c];\n                grid[r][c] = \'#\';\n                parent = buildSet(grid, m, n);\n                for(int[] d : dir) {\n                    int x = r + d[0], y = c + d[1];\n                    int rx = r - d[0], ry = c - d[1];\n                    \n                    if(x >= 0 && x < m && y >= 0 && y < n && grid[x][y] != \'#\' && rx >= 0 && rx < m && ry >= 0 && ry < n && grid[rx][ry] != \'#\') {\n                        \n                        if(find(parent, rx * n + ry) == find(parent, p[1]) && visited.add((x * n + y) + "," + p[0])) {\n                            que.offer(new int[]{x * n + y, p[0]});\n                        }\n                    }\n                }\n                grid[r][c] = (char)(res + \'0\');\n            }\n            res++;\n        }\n        return -1;\n    }\n    \n    private int[] buildSet(char[][] grid, int m, int n) {\n        int[] parent = new int[m * n];\n        for(int i = 0; i < m * n; i++) parent[i] = i;\n        for(int i = 0; i < m; i ++) {\n            for(int j = 0; j < n; j++) {\n                if(grid[i][j] != \'#\') {\n                    if(i > 0 && grid[i-1][j] != \'#\') union(parent, (i-1)*n+j, i*n+j);\n                    if(i < m-1 && grid[i+1][j] != \'#\') union(parent, (i+1)*n+j, i*n+j);\n                    if(j > 0 && grid[i][j-1] != \'#\') union(parent, i*n+j-1, i*n+j);\n                    if(j < n-1 && grid[i][j+1] != \'#\') union(parent, i*n+j+1, i*n+j);\n                }\n            }\n        }\n        return parent;\n    }\n    \n    private void union(int[] p, int a, int b) {\n        int pa = find(p, a), pb = find(p, b);\n        if(pa != pb) p[pa] = pb;\n    }\n    \n    private int find(int[] p, int a) {\n        return p[a] = p[a] == a ? a : find(p, p[a]);\n    }\n}\n```
[]