A clear explanation of greedily assigning bikes to workers based on Manhattan distance, prioritizing by distance then worker then bike index.
Problem Restatement
We have a campus as a 2D grid. We are given the positions of n workers and m bikes.
We need to assign one bike to each worker.
We assign bikes greedily:
- Find the pair
(worker, bike)with the smallest Manhattan distance. - Assign that bike to that worker.
- Remove both from consideration.
- Repeat.
If there are ties in distance, pick the smallest worker index, then smallest bike index.
Return an array where result[i] is the bike index assigned to worker i.
The official constraints state that 0 <= workers.length <= 1000 and 0 <= bikes.length <= 1000.
Input and Output
| Item | Meaning |
|---|---|
| Input | Worker positions and bike positions |
| Output | Bike assignment for each worker |
Function shape:
def assignBikes(workers: list[list[int]], bikes: list[list[int]]) -> list[int]:
...Examples
Example 1:
workers = [[0,0],[2,1]], bikes = [[1,2],[3,3]]Distances: (0,0)→(1,2): 3, (0,0)→(3,3): 6, (2,1)→(1,2): 2, (2,1)→(3,3): 3.
Minimum is 2: worker 1 gets bike 0. Then worker 0 gets bike 1.
Answer:
[1, 0]Key Insight
Compute all (distance, worker_idx, bike_idx) triples, sort them, then greedily assign.
Edge Cases
- Check the minimum input size allowed by the constraints.
- Verify duplicate values or tie cases if the input can contain them.
- Keep the return value aligned with the exact failure case in the statement.
Complexity
| Metric | Value | Why |
|---|---|---|
| Time | O(n * m * log(n * m)) | Sort all pairs |
| Space | O(n * m) | All pairs stored |
Common Pitfalls
- Do not optimize away the invariant; the code should still make it clear what condition is being maintained.
- Prefer problem-specific names over one-letter variables once the logic becomes stateful.
Implementation
class Solution:
def assignBikes(self, workers: list[list[int]], bikes: list[list[int]]) -> list[int]:
pairs = []
for i, (wr, wc) in enumerate(workers):
for j, (br, bc) in enumerate(bikes):
dist = abs(wr - br) + abs(wc - bc)
pairs.append((dist, i, j))
pairs.sort()
assigned_worker = set()
assigned_bike = set()
result = [-1] * len(workers)
for dist, w, b in pairs:
if w not in assigned_worker and b not in assigned_bike:
result[w] = b
assigned_worker.add(w)
assigned_bike.add(b)
if len(assigned_worker) == len(workers):
break
return resultTesting
def run_tests():
s = Solution()
assert s.assignBikes([[0,0],[2,1]], [[1,2],[3,3]]) == [1, 0]
assert s.assignBikes([[0,0],[1,1],[2,0]], [[1,0],[2,2],[2,1]]) == [0, 2, 1]
print("all tests passed")
run_tests()| Test | Expected | Why |
|---|---|---|
| 2 workers, 2 bikes | [1,0] | Closest pair assigned first |
| 3 workers, 3 bikes | [0,2,1] | Greedy distance order |