Skip to content

Latest commit

 

History

History

2290

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 

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 0 or 1.
  • grid[0][0] == grid[m - 1][n - 1] == 0

Related Topics:
Array, Breadth-First Search, Graph, Heap (Priority Queue), Matrix, Shortest Path

Similar Questions:

Solution 1. Dijkstra

// OJ: https://leetcode.com/problems/minimum-obstacle-removal-to-reach-corner
// Author: github.com/lzl124631x
// Time: O(MNlog(MN))
// Space: O(MN)
class Solution {
public:
    int minimumObstacles(vector<vector<int>>& A) {
        int M = A.size(), N = A[0].size(), dirs[4][2] = {{0,1},{0,-1},{1,0},{-1,0}};
        vector<vector<int>> dist(M, vector<int>(N, INT_MAX));
        typedef array<int, 3> Node; // bomb, x, y
        priority_queue<Node, vector<Node>, greater<>> pq; // a min heap that the top element has the min bomb usage
        pq.push({ 0, 0, 0 });
        dist[0][0] = 0;
        while (pq.size()) {
            auto [bomb, x, y] = pq.top();
            pq.pop();
            if (bomb > dist[x][y]) continue;
            if (x == M - 1 && y == N - 1) return bomb;
            for (auto &[dx, dy] : dirs) {
                int a = x + dx, b = y + dy;
                if (a < 0 || a >= M || b < 0 || b >= N) continue;
                int newBomb = bomb + A[a][b];
                if (newBomb < dist[a][b]) {
                    dist[a][b] = newBomb;
                    pq.push({newBomb, a, b});
                }
            }
        }
        return -1;
    }
};

Solution 2. BFS

// OJ: https://leetcode.com/problems/minimum-obstacle-removal-to-reach-corner
// Author: github.com/lzl124631x
// Time: O(MN * (M + N))
// Space: O(MN)
class Solution {
public:
    int minimumObstacles(vector<vector<int>>& A) {
        int M = A.size(), N = A[0].size(), dirs[4][2] = {{0,1},{0,-1},{1,0},{-1,0}};
        vector<vector<int>> dist(M, vector<int>(N, INT_MAX));
        typedef array<int, 3> Node;
        queue<Node> q;
        q.push({ 0, 0, 0 });
        dist[0][0] = 0;
        while (q.size()) {
            auto [x, y, bomb] = q.front();
            q.pop();
            if (bomb > dist[x][y]) continue;
            for (auto &[dx, dy] : dirs) {
                int a = x + dx, b = y + dy;
                if (a < 0 || a >= M || b < 0 || b >= N) continue;
                int newBomb = bomb + A[a][b];
                if (newBomb < dist[a][b]) {
                    dist[a][b] = newBomb;
                    q.push({a, b, newBomb});
                }
            }
        }
        return dist[M - 1][N - 1];
    }
};