Minimum-Weight Top-to-Bottom Grid Path
Reported by candidates from Google's online assessment. Pattern, common pitfall, and the honest play if you blank under the timer.
Google flagged this one in July 2025, and the grid size is the whole story. Up to 500 by 500 means 250,000 cells, so any approach that enumerates paths dies instantly. It's a minimum-cost path on a weighted grid with blocked cells, starting anywhere in the top row and ending anywhere in the bottom row. That's Dijkstra, not plain BFS, because weights vary. If you blank on the setup during the OA, StealthCoder is the invisible safety net that reads the problem and hands you the solution. Know the shape first and you won't need it.
The problem
You are given a rectangular matrix weights. A value of -1 marks a blocked cell. Every other value is a positive traversal cost. You may start at any unblocked cell in the top row. From an unblocked cell, you may move one cell up, down, left, or right, staying inside the matrix and never entering a blocked cell. The cost of a path is the sum of the weights of every cell in the path, including its starting and ending cells. Return the minimum possible cost of reaching any unblocked cell in the bottom row. Return -1 if no such path exists. Function minimumTopToBottomPath(weights: int[][]) → long Examples Example 1 weights = [[1,50,50,50],[1,1,1,50],[50,50,1,50]] return = 5 The cheapest path is (0,0) -> (1,0) -> (1,1) -> (1,2) -> (2,2), with total cost 1 + 1 + 1 + 1 + 1 = 5. It uses more moves than the direct expensive routes. Example 2 weights = [[5,1,5],[1,-1,1],[1,1,1]] return = 7 Starting at (0,0) and moving down twice costs 5 + 1 + 1 = 7. The low-cost top-middle cell cannot move down through the blocked center and needs a more expensive detour. Example 3 weights = [[1,-1],[-1,-1]] return = -1 No unblocked bottom-row cell is reachable from the only unblocked top-row cell. Constraints 1 <= weights.length <= 500 1 <= weights[i].length <= 500 Every row has the same length. Every cell is -1 or an integer in [1, 10^6]. A move changes the row or column by exactly 1, but not both.
Reported by candidates. Source: FastPrep
Pattern and pitfall
The trick is a multi-source Dijkstra. Push every unblocked top-row cell into a min-heap with its own weight as the starting distance. Pop the cheapest cell, relax its four neighbors by adding the neighbor's weight, skip any -1 cells, and stop the moment you pop a cell in the bottom row. That first bottom-row pop is the minimum. Example 1 shows why: the cheap detour beats the short expensive route, so fewest moves is the wrong objective. Common pitfalls: forgetting to count the starting cell's weight, using plain BFS, and overflowing with int. Costs can reach 250,000 times 10^6, so use 64-bit. If the heap is empty and nothing reached the bottom, return -1. Complexity is O(RC log RC). StealthCoder is your hedge in the live OA if the heap bookkeeping slips under pressure.
If you see this problem in your OA tomorrow, the play is to recognize the pattern in 30 seconds. StealthCoder buys you that recognition.
You can drill Minimum-Weight Top-to-Bottom Grid Path cold, or you can hedge it. StealthCoder runs invisibly during screen share and surfaces a working solution in under 2 seconds. The proctor sees the IDE. They don't see what's behind it. Built by an Amazon engineer who passed his OA cold and still thinks the filter is broken.
Get StealthCoderRelated leaked OAs
You've seen the question.
Make sure you actually pass Google's OA.
Google reuses patterns across OAs. Built by an Amazon engineer who passed his OA cold and still thinks the filter is broken. Works on HackerRank, CodeSignal, CoderPad, and Karat.
Minimum-Weight Top-to-Bottom Grid Path FAQ
What's the trick in this Google grid path problem?+
Treat it as multi-source Dijkstra. Seed the heap with every unblocked top-row cell at its own weight, then expand with a min-heap. The first bottom-row cell you pop holds the answer. Plain BFS fails because weights differ and fewer moves doesn't mean lower cost.
Why can't I just use BFS here?+
BFS minimizes the number of steps, not the sum of weights. Example 1 proves it: the winning path takes more moves than the direct routes because those cells cost 50. You need a priority queue so cheaper partial paths get expanded first.
Do I need a long for the answer?+
Yes. The function returns long for a reason. A path can cross up to 250,000 cells at up to 10^6 each, which overflows a 32-bit int. Store distances as 64-bit and initialize unvisited cells to a large sentinel.
How do I handle the no-path case?+
Run Dijkstra until the heap empties. If you never popped a bottom-row cell, return -1. Also skip -1 cells when seeding the top row. Example 3 covers it, where the only top cell is boxed in by blocked cells.
How do I prepare for this in 48 hours?+
Write Dijkstra on a grid from scratch twice. Practice the heap tuple of cost, row, column, a directions array, and bounds checks. Then test the three given examples by hand. Pay attention to counting the start cell's weight, since that's the off-by-one most people hit.