Solution: Minimum Cost to Make at Least One Valid Path in a Grid
Let’s solve the Minimum Cost to Make at Least One Valid Path in a Grid using the Graphs pattern.
We'll cover the following
Statement
You are given an grid[i][j]
can be:
1
: Move right, i.e., fromgrid[i][j]
togrid[i][j + 1]
.2
: Move left, i.e., fromgrid[i][j]
togrid[i][j - 1]
.3
: Move down, i.e., fromgrid[i][j]
togrid[i + 1][j]
.4
: Move up, i.e., fromgrid[i][j]
togrid[i - 1][j]
.
Note: Some signs may point outside the boundaries of the grid.
Your starting position is the top-left cell
You are allowed to change the direction of a sign in any cell, but each modification incurs a cost of 1
, and each sign can be modified only once.
Your task is to determine the minimum total cost required to ensure that at least one valid path exists from the top left to the bottom right cell.
Constraints:
grid.length
grid[i].length
grid[i][j]
Solution
The core intuition behind this algorithm is to find the minimum cost required to create at least one valid path from the top-left to the bottom-right cell in a grid, where each cell initially directs movement in one of four directions (right, left, down, or up). To model this, we use a 2D array, costGrid
, to store the minimum cost needed to reach each cell, initializing all values to infinity except the starting cell, which is set to zero. The algorithm explores all paths using 0-1 BFS with a deque
, where moves that follow the current cell’s direction incur zero cost and are pushed to the front, while changes in direction incur a cost of one and are pushed to the back. This ensures that lower-cost paths are processed first, allowing the algorithm to find the minimum cost path efficiently. For every cell processed, we examine all four possible directions, calculate the movement cost, and update the costGrid
if a cheaper cost is found. This way, the algorithm consistently prioritizes the most cost-effective paths, ultimately identifying the minimum-cost route that adheres to the grid's directional constraints.
Using the intuition above, we implement the algorithm as follows:
Store the number of rows and columns of the
grid
inn
andm
, respectively.Create a 2D array,
costGrid
, of sizen
m
, initializing all cells to the maximum integer value to represent infinite cost.Create a deque,
dq
, and push the starting cell(0, 0)
to the front, setting its cost incostGrid
to0
.Define an array,
dirs
, representing the four possible movement directions: right, left, down, and up.Enter a loop that continues as long as the
dq
is not empty:Pop the front cell from the
dq
and store its coordinates inrow
andcol
.Loop through each of the four directions in
dirs
using the indexd
:Use
row
,col
, anddirs[d]
to compute the adjacent cell coordinates asnewRow
andnewCol
.Using the helper function
isValidAndImprovable
, check if the new cell is valid and its cost can be improved. If so:Calculate the movement
cost
: if the current cell’s value matchesd + 1
, the cost is0
; otherwise, it’s1
.Check whether the new cost (
costGrid[row][col] + cost
) is less than the current cost at the adjacent cell (costGrid[newRow][newCol]
).If it is, update the cost of the adjacent cell.
Push the new cell to the back of the
dq
if the cost is1
(less optimal); push it to the front if the cost is0
(more optimal).If the cost is
1
(less optimal), push the new cell to the back of thedq
; if it is0
(more optimal), push it to the front.
After processing all paths, return the minimum cost stored in the bottom-right cell
costGrid[n - 1][m - 1]
.
The isValidAndImprovable
helper function receives costGrid
, row
, and col
, and returns TRUE if:
The
row
index is within the vertical bounds.The
col
index is within the horizontal bounds.The cost at
(row, col)
is not equal to 0, meaning the cell may still be improved.
Let’s look at the following illustration to get a better understanding of the solution:
Level up your interview prep. Join Educative to access 70+ hands-on prep courses.