1. Title
Give you a m * n grid, where each cell is either 0 (empty) or 1 (obstacle).
At each step, you can move up, down, left and right in blank cells.
If you can remove up to k obstacles, find the shortest path from the upper left corner (0, 0) to the lower right corner (m-1, n-1), and return the steps required to pass through the path.
If such a path cannot be found, - 1 is returned.
Example 1: Input: grid = [[0,0,0], [1,1,0], [0,0,0], [0,1,1], [0,0,0]], k = 1 Output: 6 Explanation: The shortest path without removing any obstacles is 10. After removing the obstacle at position (3,2), the shortest path is 6. The path is (0,0) - > (0,1) - > (0,2) - > (1,2) - > (2,2) - > (3,2) - > (4,2) Example 2: Input: grid = [[0,1,1], [1,1,1], [1,0,0]], k = 1 Output: - 1 Explanation: We need to remove at least two obstacles to find such a path. Tips: grid.length == m grid[0].length == n 1 <= m, n <= 40 1 <= k <= m*n grid[i][j] == 0 or 1 grid[0][0] == grid[m-1][n-1] == 0
Source: LeetCode
Link: https://leetcode-cn.com/problems/shortest-path-in-a-grid-with-obstacles-elimination
Copyright belongs to the network. For commercial reprint, please contact the official authorization. For non-commercial reprint, please indicate the source.
2. Problem solving
- dp[i][j][s] refers to the position (i,j), which eliminates the shortest steps of s obstacles
- First, use BFS to search the non obstacle (0) connected with the starting point, and record the steps of dp[i][j][0] at each 0 position (the number of layers of BFS)
- Then, in traversing all possible s, traversing all positions i, j, next position state ni, nj
- If (grid [Ni] [NJ] & & S + 1 < = k) is an obstacle, it can also be removed
Then dp[ni][nj][s+1] = min(dp[ni][nj][s+1], dp[i][j][s]+1) - If grid[ni][nj] is not an obstacle
Then dp[ni][nj][s] = min(dp[ni][nj][s], dp[i][j][s]+1)
class Solution { public: int shortestPath(vector<vector<int>>& grid, int k) { vector<vector<int>> dir = {{1,0},{0,1},{0,-1},{-1,0}}; int m = grid.size(), n = grid[0].size(), i, j, ni, nj, s = 0, d; vector<vector<vector<int>>> dp(m,vector<vector<int>>(n, vector<int>(k+1, INT_MAX))); // dp[i][j][s] refers to the position (i,j), which eliminates the shortest steps of s obstacles dp[0][0][0] = 0; vector<vector<bool>> vis(m, vector<bool>(n,false)); queue<vector<int>> q; q.push({0,0}); vis[0][0] = true; while (!q.empty()) //Breadth first find all 0 positions without removing obstacles { int size = q.size(); while(size--) { i = q.front()[0]; j = q.front()[1]; q.pop(); dp[i][j][0] = s;//The shortest steps without removing obstacles for(d = 0; d < 4; ++d) { ni = i+dir[d][0]; nj = j+dir[d][1]; if(ni<0 || ni >= m || nj<0 || nj >= n || vis[ni][nj] || grid[ni][nj]) continue;//It's out of bounds. It's been visited. It's an obstacle q.push({ni,nj}); vis[ni][nj] = true; } } s++; } for(s = 0; s <= k; s++) { //obstacle for(i = 0; i < m; i++) { //Location i for(j = 0; j < n; j++) { //Location j if(dp[i][j][s] == INT_MAX) continue;//Status cannot be reached, next for(d= 0; d < 4; ++d) { //Move to 4 directions, next coordinate ni = i+dir[d][0]; nj = j+dir[d][1]; if(ni<0 || ni >= m || nj<0 || nj >= n) continue;//Out of bounds, next if(grid[ni][nj] && s+1 <= k)//The next position is an obstacle, which can be removed dp[ni][nj][s+1] = min(dp[ni][nj][s+1], dp[i][j][s]+1); else if(!grid[ni][nj])//Not an obstacle dp[ni][nj][s] = min(dp[ni][nj][s], dp[i][j][s]+1); } } } } int minstep = INT_MAX; for(s = 0; s <= k; ++s) minstep = min(minstep, dp[m-1][n-1][s]); return minstep==INT_MAX ? -1 : minstep; } };
640 ms 25.2 MB
- Or direct BFS, queue memory < I, J, number of obstacle handling >
class Solution { public: int shortestPath(vector<vector<int>>& grid, int k) { vector<vector<int>> dir = {{1,0},{0,1},{0,-1},{-1,0}}; int m = grid.size(), n = grid[0].size(), i, j, ni, nj, step = 0, curs, d; vector<vector<vector<bool>>> vis(m,vector<vector<bool>>(n, vector<bool>(k+1, false))); queue<vector<int>> q; q.push({0,0,0});// i. J, s obstacle moved several times vis[0][0][0] = true; while (!q.empty()) { int size = q.size(); while(size--) { i = q.front()[0]; j = q.front()[1]; curs = q.front()[2]; if(i==m-1 && j==n-1) return step; q.pop(); for(d = 0; d < 4; ++d) { ni = i+dir[d][0]; nj = j+dir[d][1]; if(ni<0 || ni >= m || nj<0 || nj >= n) continue;//Out of bounds if(grid[ni][nj] && curs+1 <= k && !vis[ni][nj][curs+1])//It's an obstacle. It can be removed { vis[ni][nj][curs+1] = true; q.push({ni,nj,curs+1}); } else if(!grid[ni][nj] && !vis[ni][nj][curs])//Not an obstacle { vis[ni][nj][curs] = true; q.push({ni,nj,curs}); } } } step++; } return -1; } };
400 ms 41.1 MB