# LeetCode 1293. Shortest path in grid (DP/BFS)

Posted by mountaindave on Sat, 27 Jun 2020 07:38:08 +0200

## 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.length == n
1 <= m, n <= 40
1 <= k <= m*n
grid[i][j] == 0 or 1
grid == grid[m-1][n-1] == 0
```

Source: LeetCode

## 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] 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.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;
vector<vector<bool>> vis(m, vector<bool>(n,false));
queue<vector<int>> q;
q.push({0,0});
vis = true;
while (!q.empty()) //Breadth first find all 0 positions without removing obstacles
{
int size = q.size();
while(size--)
{
i = q.front();
j = q.front();
q.pop();
dp[i][j] = s;//The shortest steps without removing obstacles
for(d = 0; d < 4; ++d)
{
ni = i+dir[d];
nj = j+dir[d];
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];
nj = j+dir[d];
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.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 = true;
while (!q.empty())
{
int size = q.size();
while(size--)
{
i = q.front();
j = q.front();
curs = q.front();
if(i==m-1 && j==n-1)
return step;
q.pop();
for(d = 0; d < 4; ++d)
{
ni = i+dir[d];
nj = j+dir[d];
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

Topics: network