All edge cases:
There are many great solutions available for this post, here I will only focus on the edge cases where your code may go wrong.\n\nI will highly suggest to give 
There are many great solutions available for this post, here I will only focus on the edge cases where your code may go wrong.\n\nI will highly suggest to give it a try first otherwise this will ruin your experience \u2639\uFE0F.\n\nImp edge cases:\n\n1. Check whether there exists a path from person till the pos from which we are pushing the box.\nTC:\n```\n   [["#","#","#","#","#","#","#"],\n    ["#","S","#",".","B","T","#"],\n    ["#","#","#","#","#","#","#"]]\n\tans = -1\n```\nHere out person S in blocked by obstacles so he can\'t reach the box only hence ans will be -1\n\n2. We can\'t pass through the box so mark the box as wall before starting a path search to the pos from where you are going to push the box then unmark it after the path search.\nTC:\n```\n    [["#",".",".","#","#","#","#","#"],\n     ["#",".",".","T","#",".",".","#"],\n     ["#",".",".",".","#","B",".","#"],\n     ["#",".",".","_",".",".",".","#"],  <-\n     ["#",".",".",".","#",".","S","#"],\n     ["#",".",".","#","#","#","#","#"]]\n\t               ^\n\tans = 7\n```\ne.g.: pushing box (pos = [row][col]) up so we need to reach below the box (pos = [row+1][col]) \n```\n\t\tchar prev = grid[box_i][box_j];\n\t\tgrid[box_i][box_j] = \'#\';\n\t\tbool path = checkPath(person_i, person_j, box_i+1, box_j, grid);\n\t\tgrid[box_i][box_j] = prev;\n```\n\nWhile pushing when the box reached the pos represented by "_" then we can\'t directly go to left part without pushing the box again to left.\n\n3. We may have to do extra push (like above) so visited vector with only i, j is not sufficient so we also maintain dir from which it is pushed.\nWhat this means is you might push a box to left and then push it back to right to reach target, we need to do this if there is a case when we want to go right but its not possible without pushing the box further and then back to its original start.\nTC:\n```\n    [["#",".",".","#","T","#","#","#","#"],\n     ["#",".",".","#",".","#",".",".","#"],\n     ["#",".",".","#",".","#","B",".","#"],\n     ["#",".",".",".",".",".",".",".","#"],\n     ["#",".",".",".",".","#",".","S","#"],\n     ["#",".",".","#",".","#","#","#","#"]]\n\t ans = 8\n```\nIf you use a visited array of i, j then you won\'t be able to push it back to the same place it was before. So we also maintain one more parameter dir. vis with i, j, and dir where dir represents from which dir it was pushed.\n```\nbool vis[rows][cols][dir]; \nor\nbool vis[n][m][4] // 4 directions\n```\n\nMy code:\n```\n\nclass Solution {\npublic:\n    bool isValid(int box_i, int box_j, int person_i, int person_j, vector<vector<char>>& grid) {\n        int n = grid.size();\n        int m = grid[0].size();\n\n        if (box_i >= 0 && person_i >= 0 && box_j >= 0 && person_j >= 0 && box_i < n && person_i < n && box_j < m && person_j < m && grid[box_i][box_j] != \'#\' && grid[person_i][person_j] != \'#\') {\n            return true;\n        }\n        return false;\n    }\n\n    class Node {\n    public:\n        int box_i;\n        int box_j;\n        int person_i;\n        int person_j;\n\n        Node() {\n\n        }\n\n        Node(int boxi, int boxj, int personi, int personj) {\n            box_i = boxi;\n            box_j = boxj;\n            person_i = personi;\n            person_j = personj;\n        }\n    };\n\n    bool checkPath(int start_i, int start_j, int target_i, int target_j, vector<vector<char>>& grid) {\n        int n = grid.size();\n        int m = grid[0].size();\n        vector<vector<int>> vis(n, vector<int>(m, false));\n        vector<pair<int, int>> dir = { {-1,0},{1,0},{0,-1},{0,1} };\n\n        queue<pair<int, int>> q;\n        q.push({ start_i, start_j });\n        vis[start_i][start_j] = true;\n\n        while (q.empty() == false) {\n            auto t = q.front();\n            q.pop();\n            start_i = t.first;\n            start_j = t.second;\n\n            if (start_i == target_i && start_j == target_j) {\n                return true;\n            }\n\n            for (auto it : dir) {\n                int ni = start_i + it.first;\n                int nj = start_j + it.second;\n\n                if (ni >= 0 && ni < n && nj >= 0 && nj < m && grid[ni][nj] != \'#\' && vis[ni][nj] == false) {\n                    q.push({ ni, nj });\n                    vis[ni][nj] = true;\n                }\n            }\n        }\n\n        return false;\n    }\n\n    int getPush(int box_i, int box_j, int person_i, int person_j, vector<vector<char>>& grid) {\n        int n = grid.size();\n        int m = grid[0].size();\n\n        vector<vector<vector<int>>> vis(n, vector<vector<int>>(m, vector<int>(5, false)));\n\n        int count = 0;\n        Node curr(box_i, box_j, person_i, person_j);\n        queue<Node> q;\n        q.push(curr);\n        vis[box_i][box_j][0] = true;\n\n        bool reached = false;\n        while (q.empty() == false) {\n            int sz = q.size();\n\n            for (int r = 0; r < sz; r++) {\n                curr = q.front();\n                q.pop();\n\n                box_i = curr.box_i;\n                box_j = curr.box_j;\n                person_i = curr.person_i;\n                person_j = curr.person_j;\n\n                if (grid[box_i][box_j] == \'T\') {\n                    reached = true;\n                    break;\n                }\n\n                // boxi, boxj, personi, personj\n\n                // push box up\n                if (isValid(box_i - 1, box_j, box_i + 1, box_j, grid) && vis[box_i - 1][box_j][1] == false) {\n                    char prev = grid[box_i][box_j];\n                    grid[box_i][box_j] = \'#\';\n                    bool path = checkPath(person_i, person_j, box_i + 1, box_j, grid);\n                    grid[box_i][box_j] = prev;\n                    if (path) {\n                        q.push(Node(box_i - 1, box_j, box_i, box_j));\n                        vis[box_i - 1][box_j][1] = true;\n                    }\n                }\n                // push box left\n                if (isValid(box_i, box_j - 1, box_i, box_j + 1, grid) && vis[box_i][box_j - 1][2] == false) {\n                    char prev = grid[box_i][box_j];\n                    grid[box_i][box_j] = \'#\';\n                    bool path = checkPath(person_i, person_j, box_i, box_j + 1, grid);\n                    grid[box_i][box_j] = prev;\n                    if (path) {\n                        q.push(Node(box_i, box_j - 1, box_i, box_j));\n                        vis[box_i][box_j - 1][2] = true;\n                    }\n                }\n                // push box right\n                if (isValid(box_i, box_j + 1, box_i, box_j - 1, grid) && vis[box_i][box_j + 1][3] == false) {\n                    char prev = grid[box_i][box_j];\n                    grid[box_i][box_j] = \'#\';\n                    bool path = checkPath(person_i, person_j, box_i, box_j - 1, grid);\n                    grid[box_i][box_j] = prev;\n                    if (path) {\n                        q.push(Node(box_i, box_j + 1, box_i, box_j));\n                        vis[box_i][box_j + 1][3] = true;\n                    }\n                }\n                // push box down\n                if (isValid(box_i + 1, box_j, box_i - 1, box_j, grid) && vis[box_i + 1][box_j][4] == false) {\n                    char prev = grid[box_i][box_j];\n                    grid[box_i][box_j] = \'#\';\n                    bool path = checkPath(person_i, person_j, box_i - 1, box_j, grid);\n                    grid[box_i][box_j] = prev;\n                    if (path) {\n                        q.push(Node(box_i + 1, box_j, box_i, box_j));\n                        vis[box_i + 1][box_j][4] = true;\n                    }\n                }\n            }\n            if (reached) {\n                break;\n            }\n            count++;\n        }\n        if (reached == false) return -1;\n        return count;\n    }\n\n    int minPushBox(vector<vector<char>>& grid) {\n        int n = grid.size();\n        int m = grid[0].size();\n\n        int person_i, person_j;\n        int box_i, box_j;\n        for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) {\n            if (grid[i][j] == \'S\') {\n                person_i = i;\n                person_j = j;\n            }\n            if (grid[i][j] == \'B\') {\n                box_i = i;\n                box_j = j;\n            }\n        }\n\n        return getPush(box_i, box_j, person_i, person_j, grid);\n    }\n};\n\n```
[]