1368: Minimum-Cost-to-Make-at-Least-One-Valid-Path-in-a-Grid
Hard
table of contents
This question immediately feels like a breadth-first search question; I do not believe there are any special tricks per se, as it seems like quite a formulaic question.
In my algorithm, we initialize an m x n
grid,
costGrid
, to store the costs at each square we have
visited and a queue, currSquares
, to keep track of
all the squares we need to traverse through at each cost
level. The queue starts off with only one square (the one at
0, 0
).
While Loop:
Then, while currSquares
is not empty, we pop
the front element and check if we have visited it or not.
Note, that for every new Square that we visit, we check if
it is the bottom-right square (the square at index
position [m-1][n-1]
). If it is, then we return
the cost
value immediately.
Once currSquares
is empty (there is another
if
statement inside the while
loop to catch
this, meaning the initial while
loop is still running),
then we know we have visited every square possible at this
specific cost
level. We then swap the queues
currSquares
and nextSquares
around and repeat
the steps from the start of the while
loop.
Note, this should be enough to solve the question, however, I still
added a return costGrid[m-1][n-1]
at the end as the
non-void
function requires a return
value in
all control paths and just in case I somehow do not manage to visit
all squares.
code
class Solution {
private:
int direction[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
bool isNextSquareValid(vector<vector<int>>& grid, vector<vector<int>>& costGrid,
int &n, int &m, pair<int, int> &coords) {
<int, int> nextSquare = getNextSquare(grid, coords);
pair
return (nextSquare.first > -1)
and (nextSquare.first < n)
and (nextSquare.second > -1)
and (nextSquare.second < m)
and (costGrid[nextSquare.second][nextSquare.first] == -1);
}
<int, int> getNextSquare(vector<vector<int>>& grid, pair<int, int> &coords) {
pairint nextSquareX = coords.first
+ direction[grid[coords.second][coords.first]-1][0]
int nextSquareY = coords.second
+ direction[grid[coords.second][coords.first]-1][1];
return {nextSquareX, nextSquareY};
}
void pushValidSquares(queue<pair<int, int>> &currSquares,
<vector<int>>& costGrid,
vectorint &n, int &m, pair<int, int> &coords) {
int x = coords.first;
int y = coords.second;
if (x > 0 and costGrid[y][x-1] == -1 and costGrid[y][x] != 2)
.push({x-1, y});
currSquaresif (x < n-1 and costGrid[y][x+1] == -1 and costGrid[y][x] != 1)
.push({x+1, y});
currSquaresif (y > 0 and costGrid[y-1][x] == -1 and costGrid[y][x] != 4)
.push({x, y-1});
currSquaresif (y < m-1 and costGrid[y+1][x] == -1 and costGrid[y][x] != 3)
.push({x, y+1});
currSquares}
public:
int minCost(vector<vector<int>>& grid) {
int m = grid.size(), n = grid[0].size(), cost = 0;
<vector<int>> costGrid (m, vector<int>(n, -1));
vector<pair<int, int>> currSquares, nextSquares;
queue.push({0, 0});
currSquares
while (!currSquares.empty()) {
<int, int> coords = currSquares.front();
pair.pop();
currSquaresif (costGrid[coords.second][coords.first] == -1){
(nextSquares, costGrid, n, m, coords);
pushValidSquaresif (coords.first == n-1 and coords.second == m-1) return cost;
[coords.second][coords.first] = cost;
costGridwhile (isNextSquareValid(grid, costGrid, n, m, coords)) {
= getNextSquare(grid, coords);
coords (nextSquares, costGrid, n, m, coords);
pushValidSquaresif (coords.first == n-1 and coords.second == m-1) return cost;
[coords.second][coords.first] = cost;
costGrid}
}
if (currSquares.empty()) {
(currSquares, nextSquares);
swap++cost;
}
}
return costGrid[m-1][n-1];
}
};