You are given a 0-indexed 2D integer array grid of size m x n. Each cell has one of two values:
0 represents an empty cell,
1 represents an obstacle that may be removed.
You can move up, down, left, or right from and to an empty cell.
Return the minimum number of obstacles to remove so you can move from the upper left corner (0, 0) to the lower right corner (m - 1, n - 1).
Example 1:
Input: grid = [[0,1,1],[1,1,0],[1,1,0]]
Output: 2
Explanation: We can remove the obstacles at (0, 1) and (0, 2) to create a path from (0, 0) to (2, 2).
It can be shown that we need to remove at least 2 obstacles, so we return 2.
Note that there may be other ways to remove 2 obstacles to create a path.
Example 2:
Input: grid = [[0,1,0,0,0],[0,1,0,1,0],[0,0,0,1,0]]
Output: 0
Explanation: We can move from (0, 0) to (2, 4) without removing any obstacles, so we return 0.
Constraints:
m == grid.length
n == grid[i].length
1 <= m, n <= 105
2 <= m * n <= 105
grid[i][j] is either 0or1.
grid[0][0] == grid[m - 1][n - 1] == 0
Solutions
Solution 1: Double-Ended Queue BFS
This problem is essentially a shortest path model, but we need to find the minimum number of obstacles to remove.
In an undirected graph with edge weights of only \(0\) and \(1\), we can use a double-ended queue to perform BFS. The principle is that if the weight of the current point that can be expanded is \(0\), it is added to the front of the queue; if the weight is \(1\), it is added to the back of the queue.
If the weight of an edge is \(0\), then the newly expanded node has the same weight as the current front node, and it can obviously be used as the starting point for the next expansion.
The time complexity is \(O(m \times n)\), and the space complexity is \(O(m \times n)\). Where \(m\) and \(n\) are the number of rows and columns of the grid, respectively.