Shortest Path in a Grid with Obstacles Elimination in C++


Suppose we have a m x n grid, here each cell is either 0 or 1. 0 cell is empty and 1 is blocked. In one step, we can move up, down, left or right from and to an empty cell. We have to find the minimum number of steps to walk from the upper left corner cell (0, 0) to the lower right corner cell (m-1, n-1) given that we can eliminate at most k obstacles. If there is no such way, then return -1.

So, if the input is like

000
110
000
011
000

and k is 1, then the output will be 6, as the shortest path without eliminating any obstacle is 10. The shortest path with one obstacle elimination at position (3,2) will be 6. Such path will be (0,0) to (0,1) to (0,2) to (1,2) to (2,2) to (3,2) to (4,2).

To solve this, we will follow these steps −

  • Define a function ok(), this will check whether x and y are in range r and c or not

  • Define an array dp of size 50 x 50 x 2000

  • Define one Data structure where x, y, k and length are present.

  • From the main method do the following −

  • Fill the dp with inf

  • r := row count, c := column count

  • Define one queue q

  • Create Data object called root with (x = 0, y = 0, k, length = 0)

  • insert root into q

  • while (not q is empty), do −

    • node := first element of q

    • delete element from q

    • x := node.x, y := node.y, k := node.k, length := node.length

    • if x is same as r - 1 and y is same as c - 1, then −

      • return length

    • (increase length by 1)

    • for initialize i := 0, when i < 4, update (increase i by 1), do −

      • nx := x + dir[i, 0]

      • ny := y + dir[i, 1]

      • if nx is same as r - 1 and ny is same as c - 1, then −

        • return length

      • if ok(nx, ny, r, c) is true, then −

        • if grid[nx, ny] is same as 0, then −

          • if length < dp[nx, ny, k], then −

            • insert new data object with (x = nx, y = ny, k, length) into q

            • dp[nx, ny, k] := length

        • Otherwise

          • if k > 0 and length < dp[nx, ny, k], then −

            • insert new data object with (x = nx, y = ny, k = k - 1, length) into q

            • dp[nx, ny, k] := length

  • return -1

Let us see the following implementation to get better understanding −

Example

 Live Demo

#include <bits/stdc++.h>
using namespace std;
int dir [4][2]={{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
int dp[50][50][2000];
struct Data{
   int x, y, k, length;
   Data(int a, int b, int c, int d){
      x = a;
      y = b;
      k = c;
      length = d;
   }
};
class Solution {
   public:
   void pre(){
      for (int i = 0; i < 50; i++) {
         for (int j = 0; j < 50; j++) {
            for (int k = 0; k < 2000; k++) {
               dp[i][j][k] = INT_MAX;
            }
         }
      }
   }
   bool ok(int x, int y, int r, int c){
      return (x < r && y < c && x >= 0 && y >= 0);
   }
   int shortestPath(vector<vector<int> >& grid, int k){
      pre();
      int r = grid.size();
      int c = grid[0].size();
      queue<Data> q;
      Data root(0, 0, k, 0);
      q.push(root);
      while (!q.empty()) {
         Data node = q.front();
         q.pop();
         int x = node.x;
         int y = node.y;
         int k = node.k;
         int length = node.length;
         if (x == r - 1 && y == c - 1)
         return length;
         length++;
         for (int i = 0; i < 4; i++) {
            int nx = x + dir[i][0];
            int ny = y + dir[i][1];
            if (nx == r - 1 && ny == c - 1)
            return length;
            if (ok(nx, ny, r, c)) {
               if (grid[nx][ny] == 0) {
                  if (length < dp[nx][ny][k]) {
                     q.push(Data(nx, ny, k, length));
                     dp[nx][ny][k] = length;
                  }
               }
               else {
                  if (k > 0 && length < dp[nx][ny][k]) {
                     q.push(Data(nx, ny, k - 1, length));
                     dp[nx][ny][k] = length;
                  }
               }
            }
         }
      }
      return -1;
   }
};
main(){
   Solution ob;
   vector<vector<int>> v = {{0,0,0},{1,1,0},{0,0,0},{0,1,1},
   {0,0,0}};
   cout << (ob.shortestPath(v, 1));
}

Input

{{0,0,0},{1,1,0},{0,0,0},{0,1,1},{0,0,0}}

Output

6

Updated on: 08-Jun-2020

431 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements