2-stage DFS solution using java
I used minReach array to record minimal reach steps from 4 directions, then using dfs to walk step by step, finally return minReach of target position.\n\nclass
I used minReach array to record minimal reach steps from 4 directions, then using dfs to walk step by step, finally return minReach of target position.\n```\nclass Solution {\n    public int minPushBox(char[][] grid) {\n        int[][][] minReach = new int[grid.length][grid[0].length][4];\n        for (int i = 0; i < minReach.length; i++) {\n            for (int j = 0; j < minReach[0].length; j++) {\n                for (int k = 0; k < minReach[0][0].length; k++) {\n                    minReach[i][j][k] = -1;\n                }\n            }\n        }\n        int px = 0, py = 0, bx = 0, by = 0, tx = 0, ty = 0;\n        for (int i = 0; i < grid.length; i++) {\n            for (int j = 0; j < grid[i].length; j++) {\n                if (grid[i][j] == \'B\') {\n                    minReach[i][j][0] = 0;\n                    minReach[i][j][1] = 0;\n                    minReach[i][j][2] = 0;\n                    minReach[i][j][3] = 0;\n                    bx = i;\n                    by = j;\n                } else if (grid[i][j] == \'T\') {\n                    tx = i;\n                    ty = j;\n                } else if (grid[i][j] == \'S\') {\n                    px = i;\n                    py = j;\n                }\n            }\n        }\n        dfs(grid, minReach, bx, by, px, py, 0);\n        int result = -1;\n        for (int i = 0; i < 4; i++) {\n            if (minReach[tx][ty][i] != -1) {\n                if (result == -1) {\n                    result = minReach[tx][ty][i];\n                } else {\n                    result = Math.min(result, minReach[tx][ty][i]);\n                }\n            }\n        }\n        return result;\n    }\n\n    private void dfs(char[][] grid, int[][][] minReach, int bx, int by, int px, int py, int current) {\n        current++;\n        if (bx + 1 < grid.length && grid[bx + 1][by] != \'#\' && (minReach[bx + 1][by][0] == -1 || current < minReach[bx + 1][by][0]) && canReach(grid, bx - 1, by, px, py)) {\n            minReach[bx + 1][by][0] = current;\n            grid[bx + 1][by] = \'B\';\n            grid[bx][by] = \'.\';\n            dfs(grid, minReach, bx + 1, by, bx - 1, by, current);\n            grid[bx][by] = \'B\';\n            grid[bx + 1][by] = \'.\';\n        }\n\n        if (bx - 1 >= 0 && grid[bx - 1][by] != \'#\' && (minReach[bx - 1][by][1] == -1 || current < minReach[bx - 1][by][1]) && canReach(grid, bx + 1, by, px, py)) {\n            minReach[bx - 1][by][1] = current;\n            grid[bx - 1][by] = \'B\';\n            grid[bx][by] = \'.\';\n            dfs(grid, minReach, bx - 1, by, bx + 1, by, current);\n            grid[bx - 1][by] = \'.\';\n            grid[bx][by] = \'B\';\n        }\n\n        if (by + 1 < grid[0].length && grid[bx][by + 1] != \'#\' && (minReach[bx][by + 1][2] == -1 || current < minReach[bx][by + 1][2]) && canReach(grid, bx, by - 1, px, py)) {\n            minReach[bx][by + 1][2] = current;\n            grid[bx][by + 1] = \'B\';\n            grid[bx][by] = \'.\';\n            dfs(grid, minReach, bx, by + 1, bx, by - 1, current);\n            grid[bx][by + 1] = \'.\';\n            grid[bx][by] = \'B\';\n        }\n\n        if (by - 1 >= 0 && grid[bx][by - 1] != \'#\' && (minReach[bx][by - 1][3] == -1 || current < minReach[bx][by - 1][3]) && canReach(grid, bx, by + 1, px, py)) {\n            minReach[bx][by - 1][3] = current;\n            grid[bx][by - 1] = \'B\';\n            grid[bx][by] = \'.\';\n            dfs(grid, minReach, bx, by - 1, bx, by + 1, current);\n            grid[bx][by - 1] = \'.\';\n            grid[bx][by] = \'B\';\n        }\n    }\n\n    private boolean canReach(char[][] grid, int x, int y, int px, int py) {\n        if (x < 0 || x >= grid.length || y < 0 || y >= grid[0].length || grid[x][y] == \'#\') {\n            return false;\n        }\n        boolean[][] visit = new boolean[grid.length][grid[0].length];\n        travel(grid, px, py, visit);\n        return visit[x][y];\n    }\n\n    private void travel(char[][] grid, int px, int py, boolean[][] visit) {\n        if (px >= 0 && px < grid.length && py >= 0 && py < grid[0].length && !visit[px][py] && grid[px][py] != \'#\' && grid[px][py] != \'B\') {\n            visit[px][py] = true;\n            travel(grid, px - 1, py, visit);\n            travel(grid, px + 1, py, visit);\n            travel(grid, px, py - 1, visit);\n            travel(grid, px, py + 1, visit);\n        }\n    }\n\n    public static void main(String[] args) {\n        System.out.println(new Solution().minPushBox(new char[][]{{\'#\', \'#\', \'#\', \'#\', \'#\', \'#\'}, {\'#\', \'T\', \'#\', \'#\', \'#\', \'#\'}, {\'#\', \'.\', \'.\', \'B\', \'.\', \'#\'}, {\'#\', \'#\', \'#\', \'#\', \'.\', \'#\'}, {\'#\', \'.\', \'.\', \'.\', \'S\', \'#\'}, {\'#\', \'#\', \'#\', \'#\', \'#\', \'#\'}}));\n    }\n}\n```
[]