1368. Minimum Cost to Make at Least One Valid Path in a Grid
1368. Minimum Cost to Make at Least One Valid Path in a Grid
[Problem]
Array
Breadth-First Search
Graph
Heap (Priority Queue)
Matrix
Shortest Path
Intuition
- We need to find the minimum cost to travel from the top-left to the bottom-right corner of the grid.
- The grid contains costs for moving in different directions, i.e. you can modify the sign on a cell with
cost = 1
- Why not DFS? : DFS would be inefficient for this problem since it doesn’t guarantee the shortest path and might explore many unnecessary paths.
- BFS is chosen here because we need the shortest path based on the number of grid moves, not on weights. It efficiently handles grid-based shortest path problems.
Tip : DFS: Suitable for finding the longest path as it is more focused on exploring deep into a graph.
BFS: Suitable for finding the shortest path as it explores neighbors level by level.
Approach
- Intialize
dp
withInteger.MAX_VALUE
as we want to track the minimum cost in the cells later. Insert
(0,0,0)
in the priority queue, meaning starting with cost 0 at cell(0,0)
1 2 3 4 5 6 7 8 9 10 11
// min-heap priority queue to always "expand" the least costly path PriorityQueue<int[]> pq = new PriorityQueue<>((a, b) -> a[0] - b[0]); int[][] dp = new int[m][n]; // to store minimum cost to reach each cell // initialize dp array with maximum values for (int[] row : dp) { Arrays.fill(row, Integer.MAX_VALUE); } // cost `0` at satrt (0,0) pq.add(new int[] {0, 0, 0});
- Start from
(0,0)
with cost0
and explore the grid in all 4 possible directions. - Use the priority queue to always expand the least cost node.
Track the minimum cost to reach each grid cell using a
dp
array- For each direction, if moving to the neighboring cell results in a lower cost, update the cost and push it to the priority queue.
- Continue until reaching the bottom-right corner.
- Start from
If the priority queue is empty or we’ve already found the minimum cost to reach the bottom-right corner, return that cost.
1 2 3 4
// if already reached the last cell, return the cost if(x == m - 1 && y == n - 1){ return cost; }
Complexity Analysis
- Time Complexity: O(mn)
- Given
m x n
grid, each cell is visited once, and priority queue operations (insertions and deletion) takesO(logp)
time, wherep
is size of priority queue.
- Given
- Space Complexity: O(mn)
dp
array stores the minimum cost for each cell, so it takesO(mn)
space.pq
takesO(mn)
space in worst case.
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
class Solution {
public int minCost(int[][] grid) {
int m = grid.length; // total rows
int n = grid[0].length; // total columns
// min-heap priority queue to always "expand" the least costly path
PriorityQueue<int[]> pq = new PriorityQueue<>((a, b) -> a[0] - b[0]);
int[][] dp = new int[m][n]; // to store minimum cost to reach each cell
// initialize dp array with maximum values
for (int[] row : dp) {
Arrays.fill(row, Integer.MAX_VALUE);
}
// cost `0` at satrt (0,0)
pq.add(new int[] {0, 0, 0});
// directions: right, left, down, up
int[][] dir = {
{0, 1},
{0, -1},
{1, 0},
{-1, 0}
};
// BFS traversal
while (!pq.isEmpty()) {
int[] curr = pq.poll(); // Get cell with the least cost
int cost = curr[0];
int x = curr[1];
int y = curr[2];
// if already reached the last cell, return the cost
if(x == m - 1 && y == n - 1){
return cost;
}
// explore all 4 directions
for (int i = 0; i < 4; i++) {
int newx = x + dir[i][0];
int newy = y + dir[i][1];
// check if new position is within bounds of the grid
if (newx >= 0 && newx < m && newy >= 0 && newy < n) {
// calculate new cost for moving to this position
int newCost = cost + (grid[x][y] != i + 1 ? 1 : 0);
// if the new cost is "lower", update `dp` and add to `queue`
if (newCost < dp[newx][newy]) {
dp[newx][newy] = newCost;
pq.offer(new int[] {newCost, newx, newy});
}
}
}
}
// return minimum cost to reach the bottom-right corner [m-1][n-1]
return dp[m - 1][n - 1];
}
}
This post is licensed under CC BY 4.0 by the author.