#1368 Minimum Cost to Make at Least One Valid Path in a Grid
frequently reported atGoogle
the problem
In plain words
Each cell has a sign: 1 → right, 2 → left, 3 → down, 4 → up. From (0, 0) you follow signs for free. Changing a cell's sign costs 1 (once per cell). Return the minimum total cost so that some path reaches the bottom-right cell.
in grid = [[1,1,1,1],[2,2,2,2],[1,1,1,1],[2,2,2,2]]
out 3
Change three signs to step down at the ends of rows.
in grid = [[1,1,3],[3,2,2],[1,1,4]]
out 0
Following signs already reaches the corner.
in grid = [[1,2],[4,3]]
out 1
- 1 ≤ m, n ≤ 100
- 1 ≤ grid[i][j] ≤ 4
your turn
Try it before you peek
Read the examples, say the brute force out loud, then write code: here or on LeetCode ↗. Stuck for 20 minutes? Open one hint at a time.
Solve it in the browser
LeetCode-style: complete the class. Compiled by the real javac (Java 17) and judged right here — nothing is sent anywhere.
Solutions are hidden so you can try first. Even 20 minutes of real effort makes the answer stick far better than reading it.
Marking the problem solved, or opening every hint, also shows it.
the aha
Key insight
Moving the way the arrow points costs 0; any other direction costs 1 (you change that arrow). A graph with weights 0 and 1 → 0-1 BFS.
solutions
From brute force to optimal
Each cell has 4 outgoing edges: weight 0 for its sign's direction, 1 for the rest. Run Dijkstra.
- cost[0][0] = 0, heap {0, 0, 0}.
- Poll, skip stale, relax 4 neighbours with step 0 or 1.
- Return cost of the corner.
4mn edges, each push O(log mn).
cost grid and heap.
class Solution { // Sign 1 = right, 2 = left, 3 = down, 4 = up: DIRS[s - 1] is the move sign s points to. private static final int[][] DIRS = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}}; public int minCost(int[][] grid) { int rows = grid.length, cols = grid[0].length; int[][] cost = new int[rows][cols]; for (int[] row : cost) Arrays.fill(row, Integer.MAX_VALUE); cost[0][0] = 0; PriorityQueue<int[]> pq = new PriorityQueue<>((a, b) -> Integer.compare(a[0], b[0])); pq.offer(new int[] {0, 0, 0}); // {cost, row, col} while (!pq.isEmpty()) { int[] top = pq.poll(); int d = top[0], r = top[1], c = top[2]; if (d > cost[r][c]) continue; for (int s = 0; s < 4; s++) { int nr = r + DIRS[s][0], nc = c + DIRS[s][1]; if (nr < 0 || nc < 0 || nr >= rows || nc >= cols) continue; int step = grid[r][c] == s + 1 ? 0 : 1; // follow the sign for free, else pay 1 if (d + step < cost[nr][nc]) { cost[nr][nc] = d + step; pq.offer(new int[] {d + step, nr, nc}); } } } return cost[rows - 1][cols - 1]; }}Same graph, but weights are only 0/1: a deque replaces the heap.
- Deque starts with (0,0).
- Pop front; for each direction: free move → offerFirst, paid move → offerLast (if it improves).
- Return cost of the corner.
Each cell is pushed at most twice; 4 edges per cell.
cost grid and deque.
class Solution { // Sign 1 = right, 2 = left, 3 = down, 4 = up: DIRS[s - 1] is the move sign s points to. private static final int[][] DIRS = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}}; public int minCost(int[][] grid) { int rows = grid.length, cols = grid[0].length; int[][] cost = new int[rows][cols]; for (int[] row : cost) Arrays.fill(row, Integer.MAX_VALUE); cost[0][0] = 0; Deque<int[]> deque = new ArrayDeque<>(); deque.offerFirst(new int[] {0, 0}); while (!deque.isEmpty()) { int[] cur = deque.pollFirst(); int r = cur[0], c = cur[1]; for (int s = 0; s < 4; s++) { int nr = r + DIRS[s][0], nc = c + DIRS[s][1]; if (nr < 0 || nc < 0 || nr >= rows || nc >= cols) continue; int step = grid[r][c] == s + 1 ? 0 : 1; if (cost[r][c] + step < cost[nr][nc]) { cost[nr][nc] = cost[r][c] + step; if (step == 0) deque.offerFirst(new int[] {nr, nc}); // free move → front else deque.offerLast(new int[] {nr, nc}); // paid move → back } } } return cost[rows - 1][cols - 1]; }}in the room
How to say it in the interview
talk track
- Reframe first: "changing a sign = paying 1 to move in a different direction."
- Then: 0/1 weights → 0-1 BFS, O(mn).
traps
- Mixing up the sign order — 1 right, 2 left, 3 down, 4 up.
- Thinking you need to actually modify the grid; you never do.
what they ask next
Follow-ups
Arbitrary change costs per cell?
Weights are no longer 0/1 → switch back to Dijkstra.
before you submit
Edge cases to test
- 1 × 1 grid → 0.
- Signs that point off the grid or around in a loop: you must pay to leave.
- Sign order is 1 right, 2 left, 3 down, 4 up — mixing it up silently gives wrong answers.
practise next
Similar problems
- #2290Minimum Obstacle Removal to Reach CornerHardin Shortest Paths
- #1091Shortest Path in Binary MatrixMediumin Graphs