Quick Overview

Given a grid with blocked cells, k delivery robots and k pickup items, assign every robot exactly one item by repeatedly matching the closest remaining robot-item pair under fixed tie-breaking rules. It tests shortest-path distances on grids with obstacles and careful, deterministic greedy assignment.

Assign Robots to Nearest Pickup Items on a Grid with Obstacles

Company: Nuro

Role: Software Engineer

Category: Coding & Algorithms

Difficulty: medium

Interview Round: Technical Screen

A fleet of autonomous delivery robots operates on an `m x n` grid. There are `k` robots and `k` items waiting to be picked up, and each robot must be sent to pick up one item. Each robot should be assigned the item nearest to it; because several robots can be nearest to the same item, conflicts are resolved greedily, matching the closest robot-item pair overall first. The base version of the question uses an open grid; the follow-up adds obstacles. Your function must handle grids with blocked cells, and an open grid is simply a grid with no blocked cells. Return, for each robot, the index of the item assigned to it. ### Function Signature ```python def assign_robots(grid: list[list[int]], robots: list[list[int]], items: list[list[int]]) -> list[int]: ``` `grid[r][c]` is `0` for a free cell and `1` for a blocked cell. `robots[i] = [r, c]` and `items[j] = [r, c]` give the row and column of robot `i` and item `j`. ### Rules - A robot moves one cell per step, up, down, left or right. It never leaves the grid and never enters a blocked cell. The distance between robot `i` and item `j` is the minimum number of steps from the robot's cell to the item's cell. On a grid with no blocked cells this equals `abs(r1 - r2) + abs(c1 - c2)`. - Assignment proceeds in rounds. In each round, consider every pair of a still-unassigned robot `i` and a still-unassigned item `j`, and pick the pair with the smallest distance. If several pairs tie, pick the one with the smallest robot index `i`; if they still tie, the one with the smallest item index `j`. Assign item `j` to robot `i` and remove both from further rounds. - Rounds continue until every robot has an item. Because there are as many items as robots, every robot receives exactly one item and every item is assigned exactly once. - Return a list `result` of length `k` where `result[i]` is the index of the item assigned to robot `i`. ### Constraints - `1 <= m, n <= 50`, where `m = len(grid)` and `n = len(grid[0])`; every row has length `n`. - Each `grid[r][c]` is `0` or `1`. - `1 <= k <= 50` and `len(robots) == len(items) == k`. - Every position satisfies `0 <= r < m` and `0 <= c < n`, and every robot and every item stands on a free cell. - Robot positions are pairwise distinct, and item positions are pairwise distinct. A robot and an item may share a cell, in which case their distance is `0`. - Every item is reachable from every robot, so every distance is defined and is less than `m * n`, which is at most 2,500. ### Examples **Example 1** ```text Input: grid = [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]] robots = [[0, 0], [0, 3]] items = [[0, 2], [2, 0]] Output: [1, 0] ``` Robot 0 is 2 steps from both items. Robot 1 is 1 step from item 0 and 5 steps from item 1. The closest pair overall is robot 1 with item 0, so it is matched first, and robot 0 receives the remaining item 1. **Example 2** ```text Input: grid = [[0, 0, 0], [0, 0, 0], [0, 0, 0]] robots = [[0, 1], [2, 1]] items = [[1, 1], [1, 0]] Output: [0, 1] ``` Both robots are 1 step from item 0 and 2 steps from item 1. The two pairs at distance 1 tie, so the smaller robot index wins: robot 0 receives item 0, and robot 1 receives item 1. **Example 3** ```text Input: grid = [[0, 0, 0], [1, 1, 0], [0, 0, 0]] robots = [[0, 0], [2, 2]] items = [[2, 0], [0, 2]] Output: [1, 0] ``` The blocked cells in row 1 force robot 0 around through column 2, so it is 6 steps from item 0 and 2 steps from item 1. Robot 1 is 2 steps from each item. Three pairs tie at distance 2; the smallest robot index among them is 0, whose only pair at that distance is with item 1, so robot 0 receives item 1 and robot 1 receives item 0. If the blocked cells were ignored, all four distances would be 2 and the answer would be `[0, 1]`.

Overview: Given a grid with blocked cells, k delivery robots and k pickup items, assign every robot exactly one item by repeatedly matching the closest remaining robot-item pair under fixed tie-breaking rules. It tests shortest-path distances on grids with obstacles and careful, deterministic greedy assignment.

A fleet of autonomous delivery robots operates on an `m x n` grid. There are `k` robots and `k` items waiting to be picked up, and each robot must be sent to pick up exactly one item. Each robot should get the item nearest to it, but several robots can be nearest to the same item, so conflicts are resolved greedily: the closest robot-item pair overall is matched first. The grid may contain obstacles: `grid[r][c]` is `0` for a free cell and `1` for a blocked cell. An open grid is simply a grid with no blocked cells. `robots[i] = [r, c]` and `items[j] = [r, c]` give the row and column of robot `i` and item `j`. **Rules** - A robot moves one cell per step, up, down, left or right. It never leaves the grid and never enters a blocked cell. The distance between robot `i` and item `j` is the minimum number of steps from the robot's cell to the item's cell. On a grid with no blocked cells this equals `abs(r1 - r2) + abs(c1 - c2)`. Only blocked cells restrict movement: a route may pass through cells that hold other robots or items (as in Example 2 below). - Assignment proceeds in rounds. In each round, consider every pair of a still-unassigned robot `i` and a still-unassigned item `j`, and pick the pair with the smallest distance. If several pairs tie, pick the one with the smallest robot index `i`; if they still tie, the one with the smallest item index `j`. Assign item `j` to robot `i` and remove both from further rounds. - Rounds continue until every robot has an item. Because there are as many items as robots, every robot receives exactly one item and every item is assigned exactly once. Return a list `result` of length `k` where `result[i]` is the index of the item assigned to robot `i`. The tie-break rule fixes every choice, so the answer is unique. **Constraints** - `1 <= m, n <= 50`, where `m = len(grid)` and `n = len(grid[0])`; every row has length `n`. - Each `grid[r][c]` is `0` or `1`. - `1 <= k <= 50` and `len(robots) == len(items) == k`. - Every position satisfies `0 <= r < m` and `0 <= c < n`, and every robot and every item stands on a free cell. - Robot positions are pairwise distinct, and item positions are pairwise distinct. A robot and an item may share a cell, in which case their distance is `0`. - Every item is reachable from every robot, so every distance is defined and is less than `m * n`, which is at most 2,500. Every index and distance fits in a signed 32-bit integer. **Example 1** ```text Input: grid = [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]] robots = [[0, 0], [0, 3]] items = [[0, 2], [2, 0]] Output: [1, 0] ``` Robot 0 is 2 steps from both items. Robot 1 is 1 step from item 0 and 5 steps from item 1. The closest pair overall is robot 1 with item 0, so it is matched first, and robot 0 receives the remaining item 1. **Example 2** ```text Input: grid = [[0, 0, 0], [1, 1, 0], [0, 0, 0]] robots = [[0, 0], [2, 2]] items = [[2, 0], [0, 2]] Output: [1, 0] ``` The blocked cells in row 1 force robot 0 around through column 2, so it is 6 steps from item 0 and 2 steps from item 1. Robot 1 is 2 steps from each item. Three pairs tie at distance 2; the smallest robot index among them is 0, whose only pair at that distance is with item 1, so robot 0 receives item 1 and robot 1 receives item 0. If the blocked cells were ignored, all four distances would be 2 and the answer would be `[0, 1]`.

Constraints

  • 1 <= m, n <= 50, where m = len(grid) and n = len(grid[0]); every row has length n.
  • Each grid[r][c] is 0 or 1.
  • 1 <= k <= 50 and len(robots) == len(items) == k.
  • Every position satisfies 0 <= r < m and 0 <= c < n, and every robot and every item stands on a free cell.
  • Robot positions are pairwise distinct, and item positions are pairwise distinct. A robot and an item may share a cell, in which case their distance is 0.
  • Every item is reachable from every robot, so every distance is defined and is less than m * n, which is at most 2,500.

Examples

Input: ([[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]], [[0, 0], [0, 3]], [[0, 2], [2, 0]])

Expected Output: [1, 0]

Explanation: Source Example 1: robot 1 and item 0 (distance 1) are the closest pair and are matched first, so robot 0 gets item 1; giving each robot its nearest item in robot order would return [0, 1].

Input: ([[0, 0, 0], [0, 0, 0], [0, 0, 0]], [[0, 1], [2, 1]], [[1, 1], [1, 0]])

Expected Output: [0, 1]

Explanation: Source Example 2: both robots are 1 step from item 0; the smaller robot index wins, so robot 1 gets item 1 (resolving the tie toward the larger index would return [1, 0]).

Hints

  1. With blocked cells, a robot's distance to an item is the length of its shortest legal walk, which can be much longer than abs(r1 - r2) + abs(c1 - c2); every robot-item pair needs this walking distance.
  2. Robots are not served one after another: each round compares all remaining robot-item pairs together, so a robot's nearest item may already be gone by the time it is matched.
  3. The tie-break order is fully fixed (distance, then robot index, then item index), so every round has exactly one correct pair to pick.

Loading coding console...

Show the approach

Approach

Compute every robot-item distance first, then replay the rounds exactly as specified.

Distances: run one breadth-first search from each robot over the free cells, moving up, down, left or right and never entering a blocked cell. BFS reaches cells in nondecreasing step count, so the first time a cell is reached its count is the shortest walking distance. Cells that hold other robots or items are ordinary free cells. Reading the item cells off the search from robot i gives row i of a k x k distance table; the reachability guarantee means every entry is defined.

Assignment: repeat k rounds. In each round, scan the unassigned robots in increasing index and, for each, the unassigned items in increasing index, and replace the current best pair only when a strictly smaller distance appears. Because the scan visits pairs in (robot index, item index) order and an equal distance never replaces the best, the pair kept has the smallest distance, then the smallest robot index, then the smallest item index, which is exactly the required rule. Assign that item to that robot and mark both as used. Each round removes one robot and one item, so after k rounds every robot holds a distinct item and the result is a permutation of 0..k-1.

Edge cases: k = 1 (the only item), a robot standing on an item (distance 0, matched as early as possible), single-row or single-column corridors, routes that pass through other robots' or items' cells, and walls that make the walking distance much larger than the Manhattan distance and change which pair is closest.

Time complexity:
O(k * m * n + k^3)
Space complexity:
O(m * n + k^2)