Optimal Commute: Nearest Transit Distance in a City Grid
Company: Databricks
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Technical Screen
# Optimal Commute: Nearest Transit Distance in a City Grid
A downtown is modeled as an `m x n` grid `city`. Each cell holds one of three values:
- `0` — an open street square you can walk through.
- `1` — a building, which is impassable.
- `2` — a transit station.
From an open street square you may move one step **up, down, left, or right** into an adjacent open street square (`0`) or an adjacent transit station (`2`). You can never move into or through a building (`1`).
For each open street square, its **commute cost** is the minimum number of moves needed to reach the *nearest* transit station. A planner wants this cost for every square so they can see how well-served each part of downtown is.
## Task
Return a 2D array `dist` with the same dimensions as `city`, where:
- `dist[i][j] = 0` if `city[i][j] == 2` (the square is itself a station).
- `dist[i][j] = -1` if `city[i][j] == 1` (the square is a building).
- `dist[i][j] = k` if `city[i][j] == 0` and the nearest reachable station is exactly `k` moves away (`k >= 1`).
- `dist[i][j] = -1` if `city[i][j] == 0` but **no** station is reachable from it.
(Both buildings and unreachable open squares are reported as `-1`.)
## Input / Output Format
- Input: `city`, a list of `m` rows, each a list of `n` integers drawn from `{0, 1, 2}`.
- Output: `dist`, a list of `m` rows, each a list of `n` integers, following the rules above.
Function signature:
```
nearest_transit(city: List[List[int]]) -> List[List[int]]
```
## Constraints & Assumptions
- `1 <= m, n <= 300` (up to 90,000 cells).
- Every cell of `city` is `0`, `1`, or `2`.
- There may be zero, one, or many station cells.
- Distances count moves between cell centers; adjacency is 4-directional only (no diagonals).
- The expected solution runs in `O(m * n)` time and `O(m * n)` extra space, independent of how many stations there are.
## Example 1
Input:
```
city = [[0, 1, 2],
[0, 0, 0],
[2, 1, 0]]
```
Output:
```
[[ 2, -1, 0],
[ 1, 2, 1],
[ 0, -1, 2]]
```
Explanation: Stations sit at `(0,2)` and `(2,0)`. For example, the top-left square `(0,0)` reaches the station at `(2,0)` in 2 moves (down, down), so its commute cost is `2`. The square `(1,1)` reaches either station in 2 moves. The two building cells `(0,1)` and `(2,1)` are reported as `-1`.
## Example 2
Input:
```
city = [[2, 1, 0]]
```
Output:
```
[[0, -1, -1]]
```
Explanation: The only station is at `(0,0)`. The open square at `(0,2)` is walled off from it by the building at `(0,1)`, so it is unreachable and reported as `-1`. The building cell is also `-1`.
## Example 3
Input:
```
city = [[0, 0, 0],
[0, 2, 0],
[0, 0, 0]]
```
Output:
```
[[2, 1, 2],
[1, 0, 1],
[2, 1, 2]]
```
Explanation: A single central station fills the surrounding squares with their move-distances to it.
Quick Answer: This question evaluates a candidate's ability to apply multi-source breadth-first search to a grid-based shortest-path problem. It tests graph traversal skills, handling of blocked cells, and awareness of optimizing from a brute-force per-cell search to a single efficient pass, common in coding interviews assessing algorithmic efficiency. The scenario represents a conceptual-to-practical coding challenge in the algorithms domain.
A downtown is modeled as an `m x n` grid `city`. Each cell holds one of three values:
- `0` — an open street square you can walk through.
- `1` — a building, which is impassable.
- `2` — a transit station.
From an open street square you may move one step **up, down, left, or right** into an adjacent open street square (`0`) or an adjacent transit station (`2`). You can never move into or through a building (`1`).
For each open street square, its **commute cost** is the minimum number of moves needed to reach the *nearest* transit station.
## Task
Return a 2D array `dist` with the same dimensions as `city`, where:
- `dist[i][j] = 0` if `city[i][j] == 2` (the square is itself a station).
- `dist[i][j] = -1` if `city[i][j] == 1` (the square is a building).
- `dist[i][j] = k` if `city[i][j] == 0` and the nearest reachable station is exactly `k` moves away (`k >= 1`).
- `dist[i][j] = -1` if `city[i][j] == 0` but **no** station is reachable from it.
Both buildings and unreachable open squares are reported as `-1`.
## Constraints
- `1 <= m, n <= 300` (up to 90,000 cells).
- Every cell of `city` is `0`, `1`, or `2`.
- There may be zero, one, or many station cells.
- Adjacency is 4-directional only (no diagonals).
- Target: `O(m * n)` time and space, independent of the number of stations.
Constraints
- 1 <= m, n <= 300 (up to 90,000 cells).
- Every cell of city is 0 (open), 1 (building), or 2 (station).
- There may be zero, one, or many station cells.
- Movement is 4-directional only; buildings are impassable.
- Expected O(m * n) time and space, independent of the number of stations.
Examples
Input: ([[0, 1, 2], [0, 0, 0], [2, 1, 0]],)
Expected Output: [[2, -1, 0], [1, 2, 1], [0, -1, 2]]
Explanation: Stations at (0,2) and (2,0). (0,0) reaches (2,0) in 2 down-moves; (1,1) reaches either in 2. The buildings (0,1) and (2,1) are -1.
Input: ([[2, 1, 0]],)
Expected Output: [[0, -1, -1]]
Explanation: The lone station at (0,0) is walled off from (0,2) by the building at (0,1), so (0,2) is unreachable (-1). The building is -1 too.
Input: ([[0, 0, 0], [0, 2, 0], [0, 0, 0]],)
Expected Output: [[2, 1, 2], [1, 0, 1], [2, 1, 2]]
Explanation: A single central station fills the ring around it with move-distances; corners are 2 (diagonal takes two 4-directional moves).
Input: ([[0]],)
Expected Output: [[-1]]
Explanation: One open cell and no station anywhere, so it is unreachable and reported as -1.
Input: ([[2, 0, 1, 0, 2]],)
Expected Output: [[0, 1, -1, 1, 0]]
Explanation: Stations at both ends; the central building at index 2 splits the row, so each open cell is served by the station on its own side at distance 1.
Hints
- Running a separate BFS from each open square is O((m*n)^2) in the worst case. Flip the direction: BFS outward from the stations instead of toward them.
- Seed a single queue with ALL station cells at distance 0, then do one BFS. This multi-source BFS discovers every open cell at its minimum distance to the nearest station in one pass.
- Because you only ever enqueue an open cell the first time you reach it, its recorded distance is already minimal — no cell needs to be relaxed twice. Buildings and open cells that stay untouched keep the initial -1.